Search code examples
javaencryptionopenssldigital-signaturedigest

Converting openssl digest signing statement to Java code


I'm trying to convert an OpenSSL linux statement to Java code, but so far, I've been getting different results. It's about the following statement:

echo "testString" | openssl dgst -sha256 -sign private.key -passin "pass:passw0rd" | openssl base64 -A

This echo's the following result:

6FFS+Vym+Su887Mq0YG1OsURb7Csw9czvycShEd2P6SHQYKE7O6V/wzi5XTGJcP/sTaHvOAIZ5g8cIs5SEKD8NGaMLPD35hnNAn1nlAVfBT826pwIjUvzJII7d2aHKTjVfIhsyUEXbRtSMrrJNrtfyCTYYYOxCWzZv0RiOczQlpy1Jaa46fSacvaRKXi9xV/W1KxYcNS8wc/mc3Ujeqc4gfESb2YJU8yP3P269iENCjDq++8CTyEj4vm4XxlXYBIREEK7qUfxTTo1+XKfBck/0/RGwZD26jhRNHKMI6maW0mB+fRLjnYIvBqQKRbZnoIEmjy8AYy8CGC56Ujh2r3dg==

Now I'm trying the following Java code:

public String encryptString(byte[] data) {
    try {
        java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        Resource keyStore = ctx.getResource(keystoreLocation);
        PrivateKey privateKey = loadPrivateKey(keyStore.getInputStream());

        Signature signature = Signature.getInstance("SHA256withRSA", "BC");
        signature.initSign(privateKey);
        signature.update(data);
        String result = Base64.getEncoder().encodeToString(signature.sign());

        // return Base64.getEncoder().encodeToString(signature.sign());
        return null;
    } catch (Exception e) {
        log.error("Something went wrong during encryption.");
        throw new RuntimeException(e);
    }
}

This code ends up with the encoded result which differs from the linux statement:

uxdvp2oTaoS/Iln9KYNL+2o49fbW2Br0jIt9cc/F3xRm3XnsEVVBzKA0vL9yMCAvNvH0nfBt2nRHQzL5PtN+uLy0pKCtHBKxfgdTZjnhm0qdj6tcOIvx3f1AkrMhXAk6bfEMqxu5dEl8AJ2wvYvggyBDXn+Bv0TG+2iavNZ80RDqILExQvGSnD7O9BSPtOVtf17ahyzagYNiqEGxdqLUSZHNNs7Q10hYpeJ7cB6Jg/NRUGFS5Z14xmvjqyk63VFXw86hCvX1rnDt3vL7XRdSRKMhiI9SfnSHbNSNEMcSBRxX6nb1nkuuqjjzNBXZAduNAOBzIrrROmwQkXVOFKXDCw==

I've also tried some other things. I tried working with the Cipher implementation:

Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);

byte[] hash = digest.digest(data);
byte[] signature = cipher.doFinal(hash);

String hashEncoded = Base64.getEncoder().encodeToString(hash);
String signatureEncoded = Base64.getEncoder().encodeToString(hash);

But all the String's end up shorter than expected. I also saw the 'dgst' statement so I was wondering I had to digest the message (using MessageDigest digest = MessageDigest.getInstance("SHA-256", "BC");) but here I got the same problem, way shorter String's.

Does anybody know what I'm doing wrong here?


Solution

  • The issue here is very simple, and not particularly interesting. echo "testString" appends a newline to the string being echoed. For most versions of echo, the -n option will suppress the newline. Or, just as good, you can add the newline in the java version, say with something like:

    signature.update("testString\n".getBytes(StandardCharsets.UTF_8));