在 java 中使用私钥签署 SHA512-HMAC

Sign SHA512-HMAC with private key in java

我想构建一个函数,使用带有密码的私钥对 SHA512 HMAC 进行签名以打开该文件。我已经用 Javascript 做到了,但我无法在 JAVA 中做到。这是我在 Javascript 中的代码:-

const fs = require('fs')
const crypto = require('crypto');

const getSignatureByInput = (input, crt) => {
    let privatePem = fs.readFileSync(crt);
    let key = privatePem.toString('ascii');
    let sign = crypto.createSign('RSA-SHA512');
    sign.write(input)
    let signature = sign.sign({ key, passphrase: 'Password' }, 'hex')
    return signature;
}

// Usage
let hamc = crypto.createHmac("sha512", '12345678-73a8-414c-9832-fcd4b2d9b362').update(
    JSON.stringify({
    "body": {
        "Id": "123"
    }
})
).digest("hex");


console.log(hamc)

let signatureSignedByPrivateKey = getSignatureByInput(hamc,'./private.key');
console.log(signatureSignedByPrivateKey)

下面是我的私钥示例:-

-----BEGIN ENCRYPTED PRIVATE KEY-----
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
XfJTekUHHwFnpKVang==
-----END ENCRYPTED PRIVATE KEY-----

感谢您的支持! 提前致谢...

我找到了解决这个问题的方法,谢谢 @pra-a for answering a question posted earlier

我将在下面分享我的解决方案。

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.*;
import java.security.spec.*;


public class Main {
    public static final String PRIVATE_KEY="./private.der";

    public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
    // write your code here

        //get the private key
        File file = new File(PRIVATE_KEY);
        FileInputStream fis = new FileInputStream(file);
        DataInputStream dis = new DataInputStream(fis);

        byte[] keyBytes = new byte[(int) file.length()];
        dis.readFully(keyBytes);
        dis.close();

        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(spec);

        Mac sha512Hmac;
        String result = "";
        final String key = "'12345678-73a8-414c-9832-fcd4b2d9b362'";
        String signature = "";
        String body = "{\n" +
                "    \"body\": {\n" +
                "        \"Id\": \"123\"\n" +
                "    }\n" +
                "}";
        try {
            final String HMAC_SHA512 = "HmacSHA512";
            final byte[] byteKey = key.getBytes(StandardCharsets.UTF_8);
            sha512Hmac = Mac.getInstance(HMAC_SHA512);
            SecretKeySpec keySpec = new SecretKeySpec(byteKey, HMAC_SHA512);
            sha512Hmac.init(keySpec);
            byte[] macData = sha512Hmac.doFinal(body.getBytes(StandardCharsets.UTF_8));

            // Can either base64 encode or put it right into hex
            //result = Base64.getEncoder().encodeToString(macData);
            result = bytesToHex(macData);
            
            signature = sign(result, privKey);


        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Put any cleanup here
            System.out.println("Done");
        }
    }

    private static final char[] HEX_ARRAY = "0123456789abcdef".toCharArray();
    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }


    public static PrivateKey readPrivateKeyII(String filename) throws Exception{
        InputStream in = new FileInputStream(filename);
        byte[] privateKeydata = new byte[in.available()];
        in.read(privateKeydata);
        in.close();
        KeyFactory privateKeyFactory = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(privateKeydata);
        PrivateKey privateKey = privateKeyFactory.generatePrivate(encodedKeySpec);
        return  privateKey;
    }

    public static String sign(String plainText, PrivateKey privateKey) throws Exception {
        Signature privateSignature = Signature.getInstance("SHA512withRSA");
        privateSignature.initSign(privateKey);
        privateSignature.update(plainText.getBytes(StandardCharsets.UTF_8));

        byte[] signature = privateSignature.sign();

        return bytesToHex(signature);
    }
}