【问题标题】:Signing a text file using a pfx file in java在 java 中使用 pfx 文件对文本文件进行签名
【发布时间】:2021-10-02 07:01:51
【问题描述】:

我对 java 密码学很陌生。我正在尝试使用包含公钥、私钥和数字证书的 .pfx 文件来签署文本文件。我已经能够通过将 .pfx 文件加载到 java 密钥库来访问私钥和证书。我想使用 .pfx 文件中的私钥对数据进行签名,然后附加数字证书。

        Certificate[] certificatechain = null;
    PrivateKey signerkey = null;
    Certificate certificate = null;
    PrivateKey pvtkey = null;
    File file = new File("C:\\Users\\21617\\Desktop\\Uttara Pers\\uttararead.txt"); 
    BufferedReader br = new BufferedReader(new FileReader(file));
    Enumeration<String> aliasList;
    String alias;
    String pfxPath = "D:\\Document Signer\\Test-Class3DocumentSigner2014\\Class 3 Docsigntest.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);
    signerkey = (PrivateKey) keyStore.getKey(alias, certPassword.toCharArray());
    certificatechain = keyStore.getCertificateChain(alias);
    }

这是我希望能够使用从相应 .pfx 文件加载的内容创建数字签名的地方。 我希望能够使用从 .pfx 文件中获得的私钥和证书来做同样的事情。

        File file = new File("C:\\Users\\21617\\Desktop\\Uttara Pers\\uttararead.txt"); 
    BufferedReader br = new BufferedReader(new FileReader(file));
    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
    keyPairGen.initialize(2048);
    KeyPair pair = keyPairGen.generateKeyPair();
    PrivateKey privKey = pair.getPrivate();
    Signature sign = Signature.getInstance("SHA256withRSA");
    sign.initSign(privKey);
    byte[] bytes = "br".getBytes();
    sign.update(bytes);
    byte[] signature = sign.sign();
    String base64encodedString = Base64.getEncoder().encodeToString("signature".getBytes("utf-8"));
    System.out.println("Digital signature of the file: "+base64encodedString);  

这段代码 ^ 是我为生成原始签名而编写的。这里的签名对象是用来调用和使用这里签名所需要的其他东西。我必须为我的问题创建什么对象,它相当于这段代码中的符号对象。

我已经被困在这一点上很长一段时间了。请指出我正确的方向。谢谢。

【问题讨论】:

  • 我担心你发布代码图片对自己没有好处。为什么?
  • 欢迎来到 Stackoverflow。请编辑您的问题并添加最新代码的最小但完整运行示例。请不要使用您的代码发布图片,因为人们试图帮助您不想输入代码来检查问题所在,谢谢。
  • @MichaelFehr 谢谢。我现在添加了我的代码以供参考

标签: java cryptography certificate digital-signature private-key


【解决方案1】:

您几乎拥有所有可用于从 pfx 文件中检索 RSA 私钥和证书的功能 (这是一个 PKCS12 密钥库)。

我将您的两部分代码组合成一个完整的运行示例。对于验证,有两个选项可用:

  • 选项1:使用公钥验证签名(使用“certificate.getPublicKey()”获取密钥

  • 选项 2:使用证书验证签名

请注意,代码没有任何异常处理。选择的签名算法也是确定性的 - 有更好的签名算法可用。

这是代码的输出:

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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2011-05-11
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 2011-10-15
    • 2015-02-13
    • 2018-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多