Search code examples
pythonencryptionopensslrsa

Create compatible Java "RSA" signature using a PKCS#8 encoded private key


I have pkcs8_rsa_private_key file which generate by openssl from a rsa_private_key.pem file.

I need make a signature by the private key in python, make the same signature with below java code.

public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

public static String sign(String content, String privateKey) {
    String charset = "utf-8";
    try {
        PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
                Base64.decode(privateKey));
        KeyFactory keyf = KeyFactory.getInstance("RSA");
        PrivateKey priKey = keyf.generatePrivate(priPKCS8);

        java.security.Signature signature = java.security.Signature
                .getInstance(SIGN_ALGORITHMS);

        signature.initSign(priKey);
        signature.update(content.getBytes(charset));

        byte[] signed = signature.sign();

        return Base64.encode(signed);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

Solution

  • PKCS#8 defines a way to encode and transport secret keys and it is not specific to OpenSSL; PKCS#1 defines a way to use an RSA key (no matter how it was loaded into your application, with PKCS#8 or not) to carry out and verify digital signature on data.

    The piece of code you have does three things:

    1. It decodes Base64 into PKCS#8
    2. It decodes PKCS#8 into the actual key in memory (mind you may need to provide a passphrase here)
    3. It performs PKCS#1 v1.5 signature using SHA-1 using said key
    4. It encodes the signature in Base64

    The example for PKCS#1 v1.5 signing in the API of PyCrypto does exactly steps #2 and #3.