ถาม: ถ้าฉันเข้ารหัสไฟล์. class ของฉันและใช้ classloader ที่กำหนดเองเพื่อโหลดและถอดรหัสในทันทีการดำเนินการนี้จะป้องกันการถอดรหัสหรือไม่
ตอบ: ปัญหาในการป้องกันการถอดรหัส Java byte-code นั้นเกือบจะเป็นภาษาเก่า แม้จะมีเครื่องมือทำให้งงงวยมากมายในตลาด แต่นักเขียนโปรแกรม Java มือใหม่ยังคงคิดหาวิธีใหม่ ๆ และชาญฉลาดในการปกป้องทรัพย์สินทางปัญญาของตน ในภาค Q&A ของ Java นี้ฉันจะปัดเป่าความเชื่อผิด ๆ เกี่ยวกับแนวคิดที่มักจะได้รับการแก้ไขในฟอรัมการสนทนา
ความสะดวกอย่างยิ่งที่ไฟล์ Java .class สามารถสร้างขึ้นใหม่ในซอร์ส Java ที่มีลักษณะใกล้เคียงกับต้นฉบับนั้นมีส่วนเกี่ยวข้องกับเป้าหมายการออกแบบไบต์โค้ด Java และการแลกเปลี่ยน เหนือสิ่งอื่นใดรหัส Java byte ได้รับการออกแบบมาเพื่อความกะทัดรัดความเป็นอิสระของแพลตฟอร์มความคล่องตัวของเครือข่ายและความสะดวกในการวิเคราะห์โดยตัวแปลรหัสไบต์และ JIT (คอมไพเลอร์แบบไดนามิกในเวลาเดียว) / HotSpot โดยทั่วไปแล้วไฟล์. class ที่คอมไพล์จะแสดงเจตนาของโปรแกรมเมอร์อย่างชัดเจนดังนั้นจึงสามารถวิเคราะห์ได้ง่ายกว่าซอร์สโค้ดเดิม
ทำได้หลายอย่างถ้าไม่ป้องกันการแยกส่วนอย่างสมบูรณ์อย่างน้อยก็ทำให้ยากขึ้น ตัวอย่างเช่นในขั้นตอนหลังการคอมไพล์คุณสามารถนวดข้อมูล. class เพื่อทำให้โค้ดไบต์อ่านได้ยากขึ้นเมื่อถอดรหัสคอมไพล์หรือถอดรหัสเป็นโค้ด Java ที่ถูกต้องได้ยากขึ้น (หรือทั้งสองอย่าง) เทคนิคเช่นการใช้ชื่อเมธอดที่มากเกินไปจะทำงานได้ดีสำหรับอดีตและการจัดการโฟลว์การควบคุมเพื่อสร้างโครงสร้างควบคุมที่ไม่สามารถแสดงผ่านไวยากรณ์ของ Java ได้ดี เครื่องกำจัดขยะเชิงพาณิชย์ที่ประสบความสำเร็จมากขึ้นใช้การผสมผสานระหว่างเทคนิคเหล่านี้และเทคนิคอื่น ๆ
น่าเสียดายที่ทั้งสองวิธีต้องเปลี่ยนรหัสจริง ๆ ที่ JVM จะทำงานและผู้ใช้หลายคนกลัว (อย่างถูกต้อง) ว่าการเปลี่ยนแปลงนี้อาจเพิ่มข้อบกพร่องใหม่ให้กับแอปพลิเคชันของตน นอกจากนี้วิธีการและการเปลี่ยนชื่อฟิลด์อาจทำให้การเรียกใช้การสะท้อนหยุดทำงาน การเปลี่ยนชื่อคลาสและแพ็กเกจจริงสามารถทำลาย Java API อื่น ๆ (JNDI (Java Naming and Directory Interface) ผู้ให้บริการ URL และอื่น ๆ ) นอกเหนือจากชื่อที่เปลี่ยนแปลงแล้วหากการเชื่อมโยงระหว่างออฟเซ็ตรหัสไบต์คลาสและหมายเลขบรรทัดต้นทางมีการเปลี่ยนแปลงการกู้คืนสแต็กเทรซข้อยกเว้นเดิมอาจทำได้ยาก
จากนั้นมีตัวเลือกในการทำให้ซอร์สโค้ด Java ต้นฉบับสับสน แต่โดยพื้นฐานแล้วสิ่งนี้ทำให้เกิดปัญหาที่คล้ายกัน เข้ารหัสไม่คลุมเครือ?
บางทีข้างต้นอาจทำให้คุณคิดว่า "ถ้าแทนที่จะจัดการรหัสไบต์ฉันจะเข้ารหัสคลาสทั้งหมดของฉันหลังจากการคอมไพล์และถอดรหัสทันทีภายใน JVM (ซึ่งสามารถทำได้ด้วย classloader ที่กำหนดเอง) จากนั้น JVM จะดำเนินการของฉัน รหัสไบต์ดั้งเดิมและยังไม่มีอะไรให้ถอดรหัสหรือทำวิศวกรรมย้อนกลับใช่ไหม "
น่าเสียดายที่คุณคิดผิดทั้งที่คิดว่าคุณเป็นคนแรกที่คิดไอเดียนี้และคิดว่ามันใช้งานได้จริง และเหตุผลนั้นไม่เกี่ยวข้องกับความแข็งแกร่งของรูปแบบการเข้ารหัสของคุณ