无法在Java中获得公钥显示以匹配Adobe中的公钥显示 [英] can't get public key display in java to match those in Adobe

查看:87
本文介绍了无法在Java中获得公钥显示以匹配Adobe中的公钥显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用证书签署了pdf.在Java中,我处理pdf并提取证书详细信息.我将输出与该文档在Adobe中显示的证书详细信息进行比较.对于SerialNumber,我可以使它们看起来相同,但对于公共密钥则不能.任何帮助表示赞赏!

I sign a pdf using a certificate. In java I process the pdf and extract the certificate details. I compare the output against the certificate details shown in Adobe for that document. For SerialNumber I was able to make them look the same, but not for public key. Any help appreciated!

我调试了代码,尝试使用Hex.toHexString进行转换,并在stackoverflow中进行了谷歌搜索.但是没有运气

I debugged the code, tried to convert using Hex.toHexString, googled in stackoverflow. But no luck

System.out.println("signed? " + pdAcroForm.isSignaturesExist());
if (pdAcroForm.isSignaturesExist()) {
    PDSignatureField signatureField = (PDSignatureField) pdAcroForm.getField("signatureField");
    System.out.println("Name: " + signatureField.getSignature().getName());
    System.out.println("Name: " + signatureField.getSignature().getContactInfo());

    Security.addProvider(new BouncyCastleProvider());
    List<PDSignature> signatureDictionaries = document.getSignatureDictionaries();
    X509Certificate cert;
    Collection<X509Certificate> result = new HashSet<X509Certificate>();
    // Then we validate signatures one at the time.
    for (PDSignature signatureDictionary : signatureDictionaries) {
        // NOTE that this code currently supports only "adbe.pkcs7.detached", the most common signature /SubFilter anyway.
        byte[] signatureContent = signatureDictionary.getContents(new FileInputStream(signedFile));
        byte[] signedContent = signatureDictionary.getSignedContent(new FileInputStream(signedFile));
        // Now we construct a PKCS #7 or CMS.
        CMSProcessable cmsProcessableInputStream = new CMSProcessableByteArray(signedContent);
        try {
            CMSSignedData cmsSignedData = new CMSSignedData(cmsProcessableInputStream, signatureContent);
            Store<?> certStore = cmsSignedData.getCertificates();
            SignerInformationStore signers = cmsSignedData.getSignerInfos();
            Iterator<?> it = signers.getSigners().iterator();
            while (it.hasNext()) {
                SignerInformation signer = (SignerInformation) it.next();
                Collection<?> certCollection = certStore.getMatches(signer.getSID());
                Iterator<?> certIt = certCollection.iterator();
                while (certIt.hasNext()) {
                    X509CertificateHolder certificateHolder = (X509CertificateHolder) certIt.next();
                    System.out.println(certificateHolder.getSubjectPublicKeyInfo());
                    System.out.println(certificateHolder.getSubject());
                    System.out.println(certificateHolder.getIssuer());
                    System.out.println(Hex.toHexString(certificateHolder.getSubjectPublicKeyInfo().getPublicKeyData().getEncoded()));
                    // SerialNumber isi BigInteger in java and hex value in Windows/Mac/Adobe
                    System.out.println(certificateHolder.getSerialNumber().toString(16));

                    //result.add(new JcaX509CertificateConverter().getCertificate(certificateHolder));

                    /*PublicKey pkey = cert.getPublicKey();
                    System.out.println(pkey.toString());
                    System.out.println(cert.getNotBefore());
                    System.out.println(cert.getNotAfter());
                    System.out.println(cert.getSerialNumber());
                    System.out.println("issuer: " + cert.getIssuerDN());
                    System.out.println("subject:" + cert.getSubjectDN());
                    System.out.println("subject:" + cert.getSubjectDN());
                    System.out.println(cert.getSigAlgName());
                    */
                }
            }
        } catch (CMSException cmse) {
            cmse.printStackTrace();
        }
    }
}

在Adobe中,公钥显示如下:

In Adobe the public key is shown like this:

30 81 9F 30 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00 03 81 8D 00 30 81 89 02 81 81 00 A8 D1 52 E7 2F 58 E8 AE 62 F6 C5 77 2F 78 FA 21 46 51 B5 EF A3 A4 4C E2 EE BD A0 80 46 B6 1D 66 37 01 82 3F 65 5D 3B 0B E7 11 08 05 94 40 CF F2 EF CC BF D9 1A F6 6F 5B 0E 16 5F 85 C1 F3 D7 9D C8 C6 EF 41 09 7C A4 C3 D5 CA 1C F0 80 E6 3F BA D8 69 8F 67 67 70 FC EB 28 48 59 B3 4F F4 6B 38 E7 3B 94 0F 7C EF 2C 02 41 8A 35 A8 72 DE DE 78 DD ED 90 AD 5E 25 A3 71 DD 59 95 1C 57 24 C8 B5 02 03 01 00 01

在Java中,使用

System.out.println(Hex.toHexString(certificateHolder.getSubjectPublicKeyInfo().getPublicKeyData().getEncoded()));

SerialNumber在Java中为BigInteger,在Windows/Mac/Adob​​e中为十六进制值 它显示如下:

SerialNumber is BigInteger in java and hex value in Windows/Mac/Adobe it is shown like this:

03818d0030818902818100a8d152e72f58e8ae62f6c5772f78fa214651b5efa3a44ce2eebda08046b61d663701823f655d3b0be71108059440cff2efccbfd91af66f5b0e165f85c1f3d79dc8c6ef41097ca4c3d5ca1cf080e63fbad8698f676770fceb284859b34ff46b38e73b940f7cef2c02418a35a872dede78dded90ad5e25a371dd59951c5724c8b50203010001

对于SerialNumber,它可以正常工作. Java代码:

For SerialNumber it works fine. Java code:

System.out.println(certificateHolder.getSerialNumber().toString(16));

Java输出:

b27f048515c4f8e4

b27f048515c4f8e4

Adob​​e输出:

Adobe output:

00 B2 7F 04 85 15 C4 F8 E4

00 B2 7F 04 85 15 C4 F8 E4

非常感谢!

推荐答案

问题

区别在于Adobe显示完整的SubjectPublicKeyInfo对象的十六进制转储(包括算法信息和密钥值的公钥),而您的代码仅转储RSAPublicKey(密钥本身).

The Issue

The difference is that Adobe presents the hex dump of the complete SubjectPublicKeyInfo object (the public key including the algorithm information and the key value) while your code only dumps the RSAPublicKey (the key itself).

通过查看有关对象的ASN.1定义和两个数组的ASN.1转储,您可以更清楚地看到这一点:

You can see this clearer by looking at the ASN.1 definitions of the objects in question and an ASN.1 dump of both arrays:

   SubjectPublicKeyInfo  ::=  SEQUENCE  {
        algorithm            AlgorithmIdentifier,
        subjectPublicKey     BIT STRING  }

SubjectPublicKeyInfo

的Adobe转储

Adobe's Dump of the SubjectPublicKeyInfo

    <30 81 9F>
  0 159: SEQUENCE {
    <30 0D>
  3  13: . SEQUENCE {
    <06 09>
  5   9: . . OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
       : . . . (PKCS #1)
    <05 00>
 16   0: . . NULL
       : . . }
    <03 81 8D>
 18 141: . BIT STRING, encapsulates {
    <30 81 89>
 22 137: . . SEQUENCE {
    <02 81 81>
 25 129: . . . INTEGER    
       : . . . . 00 A8 D1 52 E7 2F 58 E8    ...R./X.
       : . . . . AE 62 F6 C5 77 2F 78 FA    .b..w/x.
       : . . . . 21 46 51 B5 EF A3 A4 4C    !FQ....L
       : . . . . E2 EE BD A0 80 46 B6 1D    .....F..
       : . . . . 66 37 01 82 3F 65 5D 3B    f7..?e];
       : . . . . 0B E7 11 08 05 94 40 CF    ......@.
       : . . . . F2 EF CC BF D9 1A F6 6F    .......o
       : . . . . 5B 0E 16 5F 85 C1 F3 D7    [.._....
       : . . . . 9D C8 C6 EF 41 09 7C A4    ....A.|.
       : . . . . C3 D5 CA 1C F0 80 E6 3F    .......?
       : . . . . BA D8 69 8F 67 67 70 FC    ..i.ggp.
       : . . . . EB 28 48 59 B3 4F F4 6B    .(HY.O.k
       : . . . . 38 E7 3B 94 0F 7C EF 2C    8.;..|.,
       : . . . . 02 41 8A 35 A8 72 DE DE    .A.5.r..
       : . . . . 78 DD ED 90 AD 5E 25 A3    x....^%.
       : . . . . 71 DD 59 95 1C 57 24 C8    q.Y..W$.
       : . . . . B5                         .
    <02 03>
157   3: . . . INTEGER 65537
       : . . . }
       : . . }
       : . }

RSAPublicKey

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

您的RSAPublicKey

转储

Your Dump of the RSAPublicKey

    <30 81 89>
  0 137: SEQUENCE {
    <02 81 81>
  3 129: . INTEGER    
       : . . 00 A8 D1 52 E7 2F 58 E8    ...R./X.
       : . . AE 62 F6 C5 77 2F 78 FA    .b..w/x.
       : . . 21 46 51 B5 EF A3 A4 4C    !FQ....L
       : . . E2 EE BD A0 80 46 B6 1D    .....F..
       : . . 66 37 01 82 3F 65 5D 3B    f7..?e];
       : . . 0B E7 11 08 05 94 40 CF    ......@.
       : . . F2 EF CC BF D9 1A F6 6F    .......o
       : . . 5B 0E 16 5F 85 C1 F3 D7    [.._....
       : . . 9D C8 C6 EF 41 09 7C A4    ....A.|.
       : . . C3 D5 CA 1C F0 80 E6 3F    .......?
       : . . BA D8 69 8F 67 67 70 FC    ..i.ggp.
       : . . EB 28 48 59 B3 4F F4 6B    .(HY.O.k
       : . . 38 E7 3B 94 0F 7C EF 2C    8.;..|.,
       : . . 02 41 8A 35 A8 72 DE DE    .A.5.r..
       : . . 78 DD ED 90 AD 5E 25 A3    x....^%.
       : . . 71 DD 59 95 1C 57 24 C8    q.Y..W$.
       : . . B5                         .
    <02 03>
135   3: . INTEGER 65537
       : . }

解决方案

解决方案很明显,而不是仅转储公钥数据

The solution

The solution is obvious, instead of dumping the public key data only

System.out.println(Hex.toHexString(certificateHolder.getSubjectPublicKeyInfo().getPublicKeyData().getEncoded()));

转储整个SubjectPublicKeyInfo对象:

System.out.println(Hex.toHexString(certificateHolder.getSubjectPublicKeyInfo().getEncoded()));

这篇关于无法在Java中获得公钥显示以匹配Adobe中的公钥显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆