我正在使用“Windows-MY”KeyStore 签署一些文本。 我想使用我的私钥签名并使用公钥验证。
KeyStore keyStore = KeyStore.getInstance("Windows-MY");
keyStore.load(null, null);
Enumeration en = keyStore.aliases();
while (en.hasMoreElements()) {
KeyStore keyStore = KeyStore.getInstance("Windows-MY");
keyStore.load(null, null);
String alias = en.nextElement().toString();
X509Certificate c = (X509Certificate) keyStore.getCertificate(alias);
String serialNumber = c.getSerialNumber().toString();
System.out.println("--" + aliasName);
PrivateKey privateKey = (PrivateKey) keyStore.getKey(aliasName, null);
PublicKey publicKey = (PublicKey) c.getPublicKey();
Certificate[] chain = keyStore.getCertificateChain(aliasName);
DataOutputStream fout = new DataOutputStream(outstream);
// -------------------------------------------------------
String data = "Monika";
byte[] content = data.getBytes();
Provider p = keyStore.getProvider();
// ----------------------signature---start---------------------------
Signature signature = Signature.getInstance("SHA256withRSA", p);
System.out.println(" signature.getProvider():"+ signature.getProvider());
signature.initSign(privateKey);
signature.update(content);
byte[] signatureBytes = signature.sign();
System.out.println("signatureBytes-------------"+ signatureBytes.toString());
// ----------------------signature----------end------------------
// ------------------------verification---------------
Signature signature1 = Signature.getInstance("SHA256withRSA", p);
System.out.println(" signature1.getProvider():"+ signature1.getProvider());
signature1.initVerify(publicKey);
signature1.update(content);
boolean verifies = signature1.verify(signatureBytes);
System.out.println("signature verifies: " + verifies);
// ------------------------------------------------
fout.close();
} // while
输出:
privateKey:RSAPrivateKey [size=2048 bits, type=Exchange, container=AC0BEBA9-A361-4611-96D9-B365B671FBC3]
signature.getProvider():SunMSCAPI version 1.6
signatureBytes-------------[B@1402d5a
signature1.getProvider():SunRsaSign version 1.5
signature verifies: false
注意:
- 我的私钥已经是 RSAPrivateKey 。
- 签名提供程序是 SunMSCAPI。
- 但我不知道 Provider for Verification with PrivateKey。
最佳答案
您的代码有几个问题:
您只是使用来自您的 Windows keystore 的第一个 证书/公钥。这实际上可能是正确的,但 keystore 中可能有多个证书,然后您使用哪个证书进行验证只是巧合。
String alias = en.nextElement().toString(); X509Certificate c = (X509Certificate) keyStore.getCertificate(alias); PublicKey publicKey = c.getPublicKey(); PrivateKey privateKey = (PrivateKey) keyStore.getKey(DSCName, null);
您应该改为编写
keyStore.getCertificate(DSCName)
以确保它与私钥匹配。您正在无缘无故地生成一个 key (分别尝试转换现有 key )。您可以完全删除此代码。这也将解决您的 NullPointerException 问题:
byte[] encodedPrivateKey = privateKey.getEncoded(); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedPrivateKey); RSAPrivateKey privateKey1 = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
您的问题中有很多不必要的代码,例如加载证书链,但从未使用它。这使得它更难修复。一个最小的(工作)示例如下所示:
String alias = "myAlias"; String myData = "data to encrypt"; KeyStore keyStore = KeyStore.getInstance("Windows-MY"); keyStore.load(null, null); X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias); PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, null); PublicKey publicKey = cert.getPublicKey(); Signature instance = Signature.getInstance("SHA256withRSA"); instance.initSign(privateKey, new SecureRandom()); instance.update(myData.getBytes("UTF-8")); byte[] signedBytes = instance.sign(); instance.initVerify(publicKey); instance.update(myData.getBytes("UTF-8")); System.out.println(instance.verify(signedBytes));
关于java - 使用 SHA256withRSA 签名后如何验证 signatureBytes?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28042594/