您几乎拥有所有可用于从 pfx 文件中检索 RSA 私钥和证书的功能
(这是一个 PKCS12 密钥库)。
我将您的两部分代码组合成一个完整的运行示例。对于验证,有两个选项可用:
请注意,代码没有任何异常处理。选择的签名算法也是确定性的 -
有更好的签名算法可用。
这是代码的输出:
RSA signature with PFX file
Private key is:SunRsaSign RSA private CRT key, 2048 bits
params: null
modulus: 20745681504295693338677598037425633054507196204877617419598634508842069647867075532992638954699743584297973637862386311040528331616364569181369404804703632552254162535558790075462853537556395029598445155559243819343605229254467273028470726088176140177653714749221474473368350858555614299113027040172126183258283581653894576374347297382002730107326970070574009149026236812216305173786045476886384540029067882067718179791112458402510855090943584133554670768670628348813208331767176300365697917644826900592782794277988966122352778692005555958605707879606264701810912582675085618198935971375640570974842583935544764079181
private exponent: 7885872371866492400523922704859047113140413382606942721776113994907817554475557100232122642774005709324978550535236092293538639199641029455823040610567723486606889193674421751986368117667957229921364507305672856973738399242981654724587068805539527352575023907603420542297516770501204867777037850752521590511057404116851028618930420914266791736061751403423747879412785083579614624025989162418565474432973854813362120531945085369119091233141833194635650026465869705622286632392621017540662631025145908079890706307098133032113785352742799568343731292342294933488080974275377487016175861831017175736029834746462206620673
certificate is: [
[
Version: V3
Subject: EMAILADDRESS=Test@Test.com, CN=Test, OU=Test, O=Test, L=Test, ST=Test, C=DE
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 2048 bits
params: null
modulus: 20745681504295693338677598037425633054507196204877617419598634508842069647867075532992638954699743584297973637862386311040528331616364569181369404804703632552254162535558790075462853537556395029598445155559243819343605229254467273028470726088176140177653714749221474473368350858555614299113027040172126183258283581653894576374347297382002730107326970070574009149026236812216305173786045476886384540029067882067718179791112458402510855090943584133554670768670628348813208331767176300365697917644826900592782794277988966122352778692005555958605707879606264701810912582675085618198935971375640570974842583935544764079181
public exponent: 65537
Validity: [From: Wed Jul 28 18:06:11 CEST 2021,
To: Sat Jul 26 18:06:11 CEST 2031]
Issuer: EMAILADDRESS=Test@Test.com, CN=Test, OU=Test, O=Test, L=Test, ST=Test, C=DE
SerialNumber: [ 7512a982 8d398731 a0e27f4d 4b0e2be2 45b2041c]
Certificate Extensions: 3
[1]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 83 B4 2A 8D 55 76 07 5F DF 2C 62 9F DC 76 69 55 ..*.Uv._.,b..viU
0010: 56 64 EE C5 Vd..
]
]
[2]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:2147483647
]
[3]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 83 B4 2A 8D 55 76 07 5F DF 2C 62 9F DC 76 69 55 ..*.Uv._.,b..viU
0010: 56 64 EE C5 Vd..
]
]
]
Algorithm: [SHA256withRSA]
Signature:
0000: 3C 69 CD 56 0B BF 4E 0E B3 8C B4 D6 C3 AB D7 C4 <i.V..N.........
...
00F0: E1 81 C5 D8 F5 90 D4 09 CA ED 12 76 8C 12 F7 A3 ...........v....
]
Digital signature of the file: LiJEB4cjSNxmcibSg5V2dgFwydvyQ4xaCJswkIHZtCPkCu17jMZszFkv6kFOhXaPLuQ49vnghXXqdXzuuX5r5y3aNyoSZMjNtk+p9cG1t+eX9FrDMkUQ7Krrl6+K/Z5vMpKlfdxC6eZx6D4qlng1isHAlVSu9yzpgE3Wxtyl7I6v5Y7kFsx+LcAztoGVpZnH8Ta96HoG+B6NhmwfsgZ2GvrN9c5jA/S3bqEb4tFplkhFAwCWWEL1PvCTMREv8Y/Y7Muew9c35hAJKdweo/CCudrSflciEUUR1Emi+Z3KzDBMNgGZQmxBnZa4X88E5HJZdHl5HHnPeB6vStQLvtyg2g==
signatureVerified: true
这里是完整的代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Enumeration;
public class TestRsaSignatureWithPfxFile {
public static void main(String[] args) throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, UnrecoverableEntryException, InvalidKeyException, SignatureException {
System.out.println("RSA signature with PFX file");
Certificate certificate = null;
PrivateKey pvtkey = null;
// load key from pfx keystore
Enumeration<String> aliasList;
String alias;
String pfxPath = "pfxCertificate.pfx", certPassword = "password";
File securityFileKeyPair = new File(pfxPath);
InputStream cerFileStream = new FileInputStream(securityFileKeyPair);
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(cerFileStream, certPassword.toCharArray());
aliasList = keyStore.aliases();
while (aliasList.hasMoreElements()) {
alias = aliasList.nextElement();
KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(certPassword.toCharArray());
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, entryPassword);
pvtkey = privateKeyEntry.getPrivateKey();
System.out.println("Private key is:" + pvtkey);
certificate = (X509Certificate) keyStore.getCertificate(alias);
System.out.println("certificate is: " + certificate);
// sign
PrivateKey privKey = pvtkey;
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initSign(privKey);
byte[] bytes = "some testdata to sign".getBytes(StandardCharsets.UTF_8);
sign.update(bytes);
byte[] signature = sign.sign();
String base64encodedString = Base64.getEncoder().encodeToString(signature);
System.out.println("Digital signature of the file: " + base64encodedString);
// verify
PublicKey pubKey = certificate.getPublicKey();
Signature verify = Signature.getInstance("SHA256withRSA");
// verification with the public key inside certificate
verify.initVerify(pubKey);
// verification with the certificate itself
//verify.initVerify(certificate);
verify.update(bytes);
boolean signatureVerified = verify.verify(signature);
System.out.println("signatureVerified: " + signatureVerified);
}
}
}