简体   繁体   中英

Java PrivateKey differs from Android

I actually have a problem with encryption in Android. For testing I created a program which generates a signature using RSA and SHA.

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;
}

Now the problem is that I get different values as PrivateKey in Java and Android. That confuses me because the method is exactly the same in both programs and it is java.security which should work in both Java and Android. I also checked all of the other values (like the byte[] etc) but they are all the same.

Do you have any help?

Encoding private key as PKCS#8 and Base64 to send it over and reconstruct private key:

@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));
}

Use android.util.Base64 instead of java.xml.bind.DatatypeConverter , which is not available on Android platform.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM