최근에 저는 Java 메시지 서버를 작성하고 있으며 클라이언트의 .NET 버전도 만들어야 합니다. 공개 키 암호화, 대칭 암호화 및 해시 알고리즘을 사용하여 몇 가지 간단한 암호화 프로토콜을 기반으로 안전하게 통신해야 합니다. 이 과정에서 저는 이 두 플랫폼의 암호화 부분에 대해 어느 정도 이해하게 되었습니다. 다음은 제가 새롭게 이해한 것 중 일부입니다.
1. 대칭 암호화
1) Java 1.5의 대칭 암호화는 매우 간단하며 더 많은 알고리즘을 제공합니다. 사용이 간편하고, 오류가 발생하지 않으며, 모든 기능이 완벽하다고 할 수 있습니다.
예를 들어:
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES")
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decryptText = cipher.doFinal(data);
2) .NET 2.0의 대칭 암호화의 경우 기본 암호화 모드는 CBC입니다. CBC를 암호화할 때 키와 초기화 벡터 IV가 필요하므로 초보자가 사용하기에는 매우 불편합니다. 처리하려면 구성을 수정하십시오.
SymmetricAlgorithm 알고리즘 = SymmetricAlgorithm.Create(algorithmName);
알고리즘.모드 = CipherMode.ECB;
알고리즘.키 = 키;
Algorithm.Padding = PaddingMode.PKCS7; 이 설정 후에는 Java와 통신하고 서로 암호화 및 복호화할 수 있습니다.
3) .NET 2.0과 Java 1.5의 경우 암호화 알고리즘의 이름이 일부 다른 경우가 있습니다.
AES <==> 린델
DE세데 <==> TripleDES
이것은 상식인 것 같습니다.
2. 공개키 암호화 알고리즘 RSA
1) Java 1.5에서는 RSAPublicKey에서 getEncoded()를 수행하여 얻은 바이트 배열이 ASN.1로 인코딩됩니다. 이를 되돌리려면 X509EncodedKeySpec을 사용해야 합니다. 이 세부 사항을 알기 위해서는 문서 세부 사항을 읽거나 암호화에 대한 특정 이해가 필요합니다. 예를 들어:
//공개 키 ==> 바이트
공개키 공개키 =
byte[] 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 구현을 빌려 .NET 버전의 ASN Parser 및 ASN Builder를 구현했는데, 이틀이 걸렸습니다. 다음과 같이:
공개 정적 RSAParameters ASN1ToPublicKey(byte[] rawPublicKey)
{
ASN1InputStream asnInput = new ASN1InputStream(rawPublicKey);
ASN1Sequence asnSeq = (ASN1Sequence)asnInput.ReadObject();
SubjectPublicKeyInfo subjectPublicKeyInfo = 새 SubjectPublicKeyInfo(asnSeq);
algOid = subjectPublicKeyInfo.AlgorithmId.ObjectId
RSAPublicKeyStructure pubKey = 새 RSAPublicKeyStructure(
(ASN1Sequence)subjectPublicKeyInfo.PublicKey)
byte[] modulus = pubKey.Modulus;
byte[] publicExComponent = pubKey.PublicExComponent
RSAParameters pram = new RSAParameters();
pram.Modulus = 모듈러스;
pram.ExComponent = publicExComponent;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(유모차)
;
}
공개 정적 바이트[] PublicKeyToASN1(RSAParameters 유모차)
{
SubjectPublicKeyInfo 정보 = 새로운 SubjectPublicKeyInfo(
새로운 AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption,
new DERNull()), new RSAPublicKeyStructure(pram.Modulus, pram.ExComponent).DERObject)
byte[] 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