เมื่อเร็วๆ นี้ ฉันกำลังเขียนเซิร์ฟเวอร์ข้อความ Java และฉันต้องสร้างไคลเอ็นต์เวอร์ชัน .NET ด้วย พวกเขาจำเป็นต้องสื่อสารอย่างปลอดภัยโดยใช้โปรโตคอลการเข้ารหัสลับง่ายๆ โดยใช้การเข้ารหัสคีย์สาธารณะ การเข้ารหัสแบบสมมาตร และอัลกอริธึมแฮช ในระหว่างกระบวนการนี้ ฉันได้รับความเข้าใจบางอย่างเกี่ยวกับส่วนการเข้ารหัสของทั้งสองแพลตฟอร์ม ต่อไปนี้เป็นความเข้าใจใหม่บางส่วนของฉัน
1. การเข้ารหัสแบบสมมาตร
1) การเข้ารหัสแบบสมมาตรของ Java 1.5 นั้นง่ายมากและมีอัลกอริธึมมากกว่า อาจกล่าวได้ว่าใช้งานง่าย ไม่หลอก และใช้งานได้เต็มรูปแบบ
ตัวอย่างเช่น:
SecretKeySpec skeySpec = SecretKeySpec ใหม่ (คีย์ "AES");
Cipher cipher = Cipher.getInstance ("AES");
cipher.init (Cipher.DECRYPT_MODE, skeySpec);
ไบต์ [] decryptText = cipher.doFinal (ข้อมูล);
2) สำหรับการเข้ารหัสแบบสมมาตรของ .NET 2.0 โหมดการเข้ารหัสเริ่มต้นคือ CBC เมื่อเข้ารหัส CBC จำเป็นต้องใช้คีย์และเวกเตอร์การเริ่มต้น ซึ่งจะทำให้ไม่สะดวกสำหรับผู้เริ่มต้นใช้งาน ปัญหานี้ร้ายแรงมาก จัดการเพียงแก้ไขการกำหนดค่า
อัลกอริธึม SymmetricAlgorithm = SymmetricAlgorithm.Create (algorithmName);
Algorithm.Mode = CipherMode.ECB;
อัลกอริทึมคีย์ = คีย์;
Algorithm.Padding = PaddingMode.PKCS7; หลังจากการตั้งค่านี้ คุณสามารถสื่อสารกับ Java และเข้ารหัสและถอดรหัสซึ่งกันและกันได้
3) ในแง่ของ .NET 2.0 และ Java 1.5 ชื่อของอัลกอริธึมการเข้ารหัสจะแตกต่างกันเล็กน้อยในบางแห่ง
เออีเอส <==> ไรน์เดล
DESede <==> TripleDES
นี่ดูเหมือนจะเป็นสามัญสำนึก
2. อัลกอริธึมการเข้ารหัสคีย์สาธารณะ RSA
1) ใน Java 1.5 อาร์เรย์ไบต์ที่ได้รับจากการดำเนินการ getEncoded() บน RSAPublicKey จะถูกเข้ารหัส ASN.1 หากต้องการย้อนกลับ คุณต้องใช้ X509EncodedKeySpec คุณต้องอ่านรายละเอียดเอกสารหรือมีความเข้าใจเกี่ยวกับการเข้ารหัสจึงจะทราบรายละเอียดนี้ ตัวอย่างเช่น:
//กุญแจสาธารณะ ==> ไบต์
พับลิกคีย์ พับลิคคีย์ =
ไบต์ [] rawPublicKey = publicKey.getEncoded ();
// ไบต์ ==> กุญแจสาธารณะ
X509EncodedKeySpec x509KeySpec = ใหม่ X509EncodedKeySpec(rawPublicKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
คีย์ newPublicKey = keyFactory.generatePublic (x509KeySpec);
นอกจากนี้ส่วนการเข้ารหัสคีย์สาธารณะของ Java นั้นค่อนข้างใช้งานง่าย สไตล์ยังคงเรียบง่ายในการใช้งาน ไม่หลอกตา และใช้งานได้เต็มรูปแบบ
ใน Java รองรับการเข้ารหัส ASN.1 แต่จะถูกซ่อนไว้และผู้ใช้มองไม่เห็นโดยสิ้นเชิง
2) ใน .NET 2.0 การออกแบบอาจดูสับสนเล็กน้อยและไม่รองรับการเข้ารหัส ASN.1 แต่ดูเหมือนว่า Mono จะรองรับการเข้ารหัส ASN.1 ด้วยเหตุนี้ ฉันจึงยืมการใช้งาน Java Kaiyuan JCE และใช้งาน ASN Parser และ ASN Builder เวอร์ชัน .NET ซึ่งใช้เวลาสองวัน ดังต่อไปนี้:
RSAParameters คงที่สาธารณะ ASN1ToPublicKey (ไบต์ [] rawPublicKey)
-
ASN1InputStream asnInput = ASN1InputStream ใหม่ (rawPublicKey);
ASN1Sequence asnSeq = (ASN1Sequence)asnInput.ReadObject();
SubjectPublicKeyInfo subjectPublicKeyInfo = ใหม่ SubjectPublicKeyInfo(asnSeq);
DERObjectIdentifier algOid = subjectPublicKeyInfo.AlgorithmId.ObjectId
;
(ASN1Sequence) subjectPublicKeyInfo.PublicKey);
ไบต์ [] โมดูลัส = pubKey.Modulus;
ไบต์ [] publicExponent = pubKey.PublicExponent;
RSAParameters pram = ใหม่ RSAParameters ();
รถเข็นเด็กโมดูลัส = โมดูลัส;
pram.Exponent = publicExponent;
RSACryptoServiceProvider rsa = ใหม่ RSACryptoServiceProvider();
rsa.ImportParameters(รถเข็นเด็ก)
;
}
ไบต์สาธารณะแบบคงที่ [] PublicKeyToASN1 (RSAParameters pram)
-
ข้อมูล SubjectPublicKeyInfo = ใหม่ SubjectPublicKeyInfo(
AlgorithmIdentifier ใหม่ (PKCSObjectIdentifiers.rsaEncryption,
ใหม่ DERNull()), RSAPublicKeyStructure ใหม่ (pram.Modulus, pram.Exponent).DERObject);
ไบต์ [] rawPublicKey = info.GetDERencoded();
ส่งคืน rawPublicKey;
}
3. ความรู้สึกโดยรวม
1) โมดูลความปลอดภัยของ Java ได้รับการออกแบบมาอย่างดี เรียบง่ายและใช้งานง่าย และมีฟังก์ชันที่ครบครัน
2) .NET 2.0 ค่อนข้างยุ่งเล็กน้อย รูปแบบการตั้งชื่อและเฟรมเวิร์กของระบบค่อนข้างไม่สอดคล้องกัน ขาดฟังก์ชัน และการจัดระเบียบโค้ดไม่เหมาะ
3) ใน Mono การสนับสนุนด้านความปลอดภัยนั้นดีกว่าที่ Microsoft เปิดตัว คุณสามารถดูได้จากอินเทอร์เน็ตว่าคุณสมบัติบางอย่างของ .NET Framework 2.0 นั้นยืมมาจาก Mono เช่นกัน
4) อาจถือได้ว่าทีมพัฒนาของโมดูลการเข้ารหัส .NET อาจไม่มีความสามารถมากนัก ดังคำกล่าวที่ว่า "การเขียนโค้ดที่ไม่ถูกต้องไม่ใช่ของเรา"
http://www.cnblogs.com/jobs/archive/2006/09/22/512297.html