2012-03-12 3 views
0

Java 웹 서비스에서 PublickKey (PEM 문자열로)를 가져 와서 PublicKey에 의해 암호화 된 웹 서비스에 데이터를 제출하는 방법을 클라이언트에서 공개하는 요구 사항이 있습니다. 이 서비스의 클라이언트는. NET 응용 프로그램입니다. 아래와 같이 자바 측 키스트 (RSA 1024 비트) 키 쌍으로 만들어 keytool.exe -genkey -alias ABC -keystore sample.ks -storetype JCEKS -storepass XYZ.NET을 사용한 공용 키 암호화 및 Java를 사용한 암호 해독

닷넷 클라이언트의 PublicKey를 취득 공개 키를 사용하여 일부 중요한 데이터를 암호화하여 암호화 된 데이터로 웹 서비스를 호출 할 수 있습니다. 웹 서비스는 키 스토어에서 사용할 수있는 개인 키를 사용하여 데이터를 해독하고 내용을 DB에 저장합니다. 클라이언트 호환성 이유로 WS-Security 기능을 사용할 수 없습니다.

웹 서비스는 키 저장소를 읽고 공개 키를 PEM 문자열로 반환합니다. .NET 클라이언트는 PublicKey를 PEM 문자열로 가져오고이를 사용하여 RSACryptoServiceProvider를 만들고 아무 문제없이 작동합니다. 그런 다음 데이터를 암호화하고 다시 Java 웹 서비스에 제출합니다.

자바 서비스는 데이터를 암호 해독하지만 내가 갖고있는 문제는 가비지 (ASCII 데이터가 아님)를 인쇄한다는 것입니다. 예외가 발생하지 않습니다.

내가 여기에 코드 (간체) 코드 조각

.NET 클라이언트 측

var registrationService = new RegistrationService(); 
    var pKey = registrationService.getPublickey(); 
    //pKey is a PEM String 
    X509Certificate2 cert = new X509Certificate2(ASCIIEncoding.ASCII.GetBytes(pKey)); 

    RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PublicKey.Key; 

    var encryptedMsg = rsa.Encrypt(Encoding.UTF8.GetBytes("Secret Data"), false); 
    var encoded_msg = Convert.ToBase64String(encryptedMsg); 

    registrationService.submitRegistration(encoded_msg); 

자바 측면을 첨부 : 주목해야 할

public void submitRegistration(String inputData) 
    { 
    //Decoding the encoded and encrypted message in the webservice  
    PrivateKey privateKey = getPrivateKeyFromKeyStore("abc"); 
    //I know I am using JDK proprietary classes, but I can easily replace this 
    byte[] dataInBytes = new Base64Decoder().deodeBuffer(inputData) 

    Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding"); 
    cipher.init(Cipher.DECRYPT_MODE, privateKey); 
    byte[] decryptedData = cipher.doFinal(dataInBytes);   
    String original = new String(decryptedData, "UTF-8"); 
    System.out.println("Original Data : " + original); 
} 
    public String getPublicKey() 
    { 
    Certificate cert = getKeyStore().getCertificate("abc"); 
    byte[] encodedCert = cert.getEncoded(); 
    StringWriter sw = new StringWriter(); 
    sw.write("-----BEGIN PUBLIC KEY-----"); 
    sw.write(new Base64Encoder().encode(encodedCert)); 
    sw.write("-----END PUBLIC KEY-----"); 
    return sw.toString(); 
    } 
+1

이 사이트를 검색 했습니까? 나는 여러 번 비슷한 질문을 많이 보았다. –

+0

예, 사이트를 검색했습니다. 비슷한 문제가 내가 직면 한 문제를 해결할 수있는 답을 찾을 수 없다는 것을 알 수 있습니다. 또한 내가 가지고있는 미묘한 변형은 웹 서비스를 통해 PublicKey를 파일로부터 읽지 않도록해야한다는 것이다. 다른 누군가가 비슷한 문제를 가지고 있고 포인터를 던져 주는지 궁금합니다. – Kris

+4

.NET 측에서 PKCS # 1 패딩을 사용하지만 Java 측에서는 패딩을 사용하지 않습니다. NoPadding을 PKCS1PADDING으로 변경하십시오. –

답변

2

한 것은 당신이있어 것입니다 Java 측에서 "NOPADDING"을 사용하지만 .NET은 PKCS1Padding을 사용합니다.

고수준 끝에 PKCS1 패딩 패드의 일반 텍스트가 0x00 0x02로되어 있기 때문에 해독 측에서 올바른 개인 키를 사용하고 있는지 확인하는 방법을 제공합니다. 그러나 잘못된 키가 0x00 0x02로 시작하는 일반 텍스트로 해독 될 확률은 적어도 1/65536이므로 잘못된 개인 키를 검색하기 위해이 확인을 완전히 신뢰할 수는 없습니다. 귀하의 경우 잘못된 키를 사용했으며 일반 텍스트가이 검사에 실패 했으므로 예외가 발생했습니다. 이제, NOPADDING을 지정하면 모든 일반 텍스트가 유효하다는 것을 나타내고, 추가 확인은 응용 프로그램에 의해 수행됩니다.

+0

해독이 갑자기 작동하면 1/64Ki 문제인 +1 흥미 롭습니다. 암호 텍스트에 대한 보안 무결성 검사 (서명이 좋을 것임)를 만드는 것은 항상 의미가 있습니다. –