[英]Using Java 7 to Verify OpenSSL Generated S/MIME Digital Signature Files
[英]Verify a signature in Java using OpenSSL generated key and certificate
下面的 Java 8 代码导致消息“签名未由匹配密钥签名”,我不明白为什么。 任何想法为什么不验证?
我最好的猜测是,这与 openssl 生成私钥或证书的方式有关,但从我的研究来看,我似乎使用了正确的命令。 我想要做的是加载一个私钥,签署一条消息,然后根据 x509 证书中包含的公钥验证签名。
privatekey.pkcs8.key 文件是使用以下命令使用基于 MS Windows 的 openssl 生成的:
openssl.exe" genrsa -out privatekey.pem 1024
openssl pkcs8 -in privatekey.pem -inform PEM -topk8 -out privatekey.pkcs8.key -outform DER -nocrypt
publickey.cer 也是使用基于 MS windows 的 openssl 生成的,使用以下命令:
openssl req -x509 -key privatekey.pem -days 365 -out publickey.cer -new
我一直在尝试验证签名的 Java 代码如下:
public static void main(String[] args) throws Exception{
new TestSigs();
}
public TestSigs {
byte[] signature = generateSignatureForMessage("src/cryptoprivatekey.pkcs8.key", "Hello");
verifySignature("src/crypto/publickey.cer", signature);
}
public byte[] generateSignatureForMessage(String privateKeyPath, String message) throws Exception {
RSAPrivateKey privKey = loadPrivateRSAKeyFromFile(privateKeyPath);
Signature s = Signature.getInstance("SHA256withRSA");
s.initSign(privKey);
s.update(ByteBuffer.wrap(message.getBytes()));
byte[] signature = s.sign();
return signature;
}
private void verifySignature(String publicKeyPath, byte[] signature) throws Exception {
Certificate cert = loadCertificate(publicKeyPath);
Signature s = Signature.getInstance("SHA256withRSA");
s.initVerify(cert);
if(s.verify(signature)) {
System.out.println("signature signed by matching key");
} else {
System.out.println("signature NOT signed by matching key");
}
}
private Certificate loadCertificate(String filename) throws FileNotFoundException, CertificateException {
FileInputStream fis = new FileInputStream(filename);
BufferedInputStream bis = new BufferedInputStream(fis);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
return cf.generateCertificate(bis);
}
private RSAPrivateKey loadPrivateRSAKeyFromFile(String keyPath) throws Exception {
byte[] privKeyBytes = loadRSAKeyBytesFromFile(keyPath);
KeyFactory kFact = KeyFactory.getInstance("RSA");
KeySpec ks = new PKCS8EncodedKeySpec(privKeyBytes);
return (RSAPrivateKey)kFact.generatePrivate(ks);
}
您对verifySignature
方法的签名( verifySignature
关语)表明您的实现无法工作。 要检查Signature
,处理器需要访问签名数据和签名。 您的方法不提供:
private void verifySignature(String publicKeyPath, byte[] signature)
我建议您将其修改为与generateSignatureForMessage
方法对称,即:
sign
或verify
)加起来就是一个类似于:
private void verifySignature(String publicKeyPath, byte[] signature, byte[] signedContent) throws Exception {
Certificate cert = loadCertificate(publicKeyPath);
Signature s = Signature.getInstance("SHA256withRSA");
s.initVerify(cert);
s.update(signedContent);
if(s.verify(signature)) {
System.out.println("signature signed by matching key");
} else {
System.out.println("signature NOT signed by matching key");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.