数字签名验证失败 - Java

时间:2018-05-16 08:04:50

标签: java digital-signature verification

我使用以下方法生成数字签名,有效负载为“hello world”

public String generateSignature(String payload) throws Exception{
        Signature rsa = null;
        rsa = Signature.getInstance("SHA256WithRSA/PSS", new BouncyCastleProvider());
        rsa.initSign(getPrivateKey("Keys/private_key"));
        rsa.update(payload.getBytes(StandardCharsets.UTF_8));
        byte[] signatureBytes = Base64.encodeBase64(rsa.sign());
        String signature = DatatypeConverter.printHexBinary(signatureBytes);
        return signature;
    }

我正在使用有效负载“hello world”验证签名,并使用generateSignatue方法获得签名。

public boolean validateSignature(String payload, String signature) throws Exception {
    Signature sig = Signature.getInstance("SHA256WithRSA/PSS", new BouncyCastleProvider());
    boolean isValid = false;
    sig.initVerify(getPublicKey("Keys/public_key"));                
    sig.update(payload.getBytes(StandardCharsets.UTF_8));
    isValid = sig.verify(Base64.decodeBase64(signature.getBytes("UTF-8")));
    return isValid;
}

这总是将isValid返回为false,这是什么错误?

检索公钥&具有以下功能的私钥(供参考):

public static PublicKey getPublicKey(String filename) throws Exception {
        byte[] keyBytes = Files.readAllBytes(Paths.get(filename));
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
    }

public static PrivateKey getPrivateKey(String filename) throws Exception {
    byte[] keyBytes = Files.readAllBytes(Paths.get(filename));
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePrivate(spec);
}

1 个答案:

答案 0 :(得分:0)

我一眼就能看到一些错误:

  • DER文件包含证书,而不是私钥。你有"Keys/private_key.der"的错字吗?

  • 您的签名代码将签名字节编码为base64和hex,但您的验证码仅从base64解码。删除此String signature = DatatypeConverter.printHexBinary(signatureBytes);您还可以删除base64转换,并使用byte[]直接使用这两种方法

  • 在编辑后的代码中,十六进制消失了,但您需要使用签名的base 64解码。此外,您必须确保使用已知的良好基础64编解码器,例如Base64.getEncoder()Base64.getDecoder()