2014-10-15 1 views
2

Android에서 암호화에 문제가 있습니다. 테스트를 위해 RSA와 SHA를 사용하여 서명을 생성하는 프로그램을 만들었습니다.Java PrivateKey가 Android와 다릅니다

public static byte[] generateKey(String privKeyModulus, String privKeyD, String encryptCredentials) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, UnsupportedEncodingException, SignatureException { 

    byte[] modulusBytes = Base64.getDecoder().decode(privKeyModulus.getBytes()); 
    byte[] dBytes = Base64.getDecoder().decode(privKeyD.getBytes()); 


    BigInteger modulusInt = new BigInteger(1, modulusBytes); 
    BigInteger dInt = new BigInteger(1, dBytes); 

    RSAPrivateKeySpec rsaPrivKey = new RSAPrivateKeySpec(modulusInt, dInt); 
    KeyFactory factory = KeyFactory.getInstance("RSA"); 

    PrivateKey privKey = factory.generatePrivate(rsaPrivKey); 


    // Here is the problem: 
    System.out.println(Arrays.toString(privKey.getEncoded())); 

    Signature sig = Signature.getInstance("SHA1withRSA"); 
    sig.initSign(privKey); 
    sig.update((encryptCredentials).getBytes("UTF-16LE"));   
    byte[] signature = sig.sign(); 

    return signature; 
} 

이제 Java와 Android에서 PrivateKey와 다른 값을 얻게되었습니다. 그 방법은 두 프로그램 모두에서 정확히 동일하기 때문에 혼란 스럽습니다. Java와 Android에서 모두 작동해야하는 java.security입니다. 다른 모든 값 (예 : byte [] 등)도 확인했지만 모두 동일합니다.

어떤 도움이 필요합니까? PKCS # 8과 Base64로 같은

+0

글쎄, java.security는 보안 공급자와의 인터페이스로, Oracle Java 및 Android의 "SunJCE"는 자체 구현이며 "AndroidOpenSSL"이 기본값입니다. – divanov

+0

감사합니다. 그것은 문제 일 수 있습니다. OpenSSL 방식으로 구현하는 방법을 알고 있습니까? – DieBergruft

+0

나는 이것이 문제라고 생각하지 않는다. 문제의 핵심 샘플이 없으므로 문제가 무엇인지 말하기가 매우 어렵습니다. Snippet은 Android에서 사용할 수없는 java.util.Base64를 사용하는 것으로 보입니다. PKCS # 8과 같은 표준 형식을 사용하여 키를 전송하는 것이 어떻습니까? – divanov

답변

0

인코딩 개인 키를 보내와 개인 키 재구성하기 :

@Test 
public void testKeyConversion() throws GeneralSecurityException { 

    /* Generate random key pair */ 
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 
    AlgorithmParameterSpec spec = new RSAKeyGenParameterSpec(1024, RSAKeyGenParameterSpec.F4); 
    keyPairGenerator.initialize(spec, new SecureRandom()); 
    KeyPair keyPair = keyPairGenerator.generateKeyPair(); 

    /* Encode private key as PKCS#8 base64 string */ 
    byte[] privKeyBytes = keyPair.getPrivate().getEncoded(); 
    String privKeyStr = DatatypeConverter.printBase64Binary(privKeyBytes); 

    /* Decode private key as PKCS#8 base64 string */ 
    byte[] privKeyBytes2 = DatatypeConverter.parseBase64Binary(privKeyStr); 
    KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
    PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(privKeyBytes2); 
    PrivateKey privateKey = keyFactory.generatePrivate(privSpec); 

    /* Ensure key is the same */ 
    byte[] privKeyBytes3 = privateKey.getEncoded(); 
    assertEquals(
      DatatypeConverter.printHexBinary(privKeyBytes), 
      DatatypeConverter.printHexBinary(privKeyBytes3)); 
} 

사용 android.util.Base64 대신 java.xml.bind.DatatypeConverter, 안드로이드 플랫폼에서 사용할 수 없습니다.

+1

이 예제를 이용해 주셔서 감사합니다. 나는 이것을 이해하고 사용하려고 노력할 것이다. – DieBergruft