【问题标题】:How to convert OpenSSL digital signature to ASN1?如何将 OpenSSL 数字签名转换为 ASN1?
【发布时间】:2016-10-25 18:47:25
【问题描述】:

使用 openssl 库,我创建了一个文件的数字签名。

如果我使用 openssl 命令,我可以看到:

openssl rsautl -verify -inkey pubkey.pem -pubin -asn1parse -in sigfile

我得到了一个不错的输出,例如:

0:d=0  hl=2 l=  49 cons: SEQUENCE          
2:d=1  hl=2 l=  13 cons:  SEQUENCE          
4:d=2  hl=2 l=   9 prim:   OBJECT            :sha256
15:d=2  hl=2 l=   0 prim:   NULL              
17:d=1  hl=2 l=  32 prim:  OCTET STRING      
  0000 - c9 8c 24 b6 77 ef f4 48-60 af ea 6f 49 3b ba ec   ..$.w..H`..oI;..
  0010 - 5b b1 c4 cb b2 09 c6 fc-2b bb 47 f6 6f f2 ad 31   [.......+.G.o..1

如何以编程方式将我的签名文件转换为我可以解析的 ASN1?

【问题讨论】:

  • 你看到的输出是not ASN.1,它是编码ASN.1的字符串表示,专为阅读和调试而设计。那么你真正要问的是什么?
  • 我知道输出不是 asn.1,我也知道签名也不是。我的问题是 openssl 是如何从签名转到一些 asn.1 的,然后他们可以解析并显示那个漂亮的字符串表示......
  • openssl 的输出是一个 ASN.1 序列,其中包含 RSA 签名的恢复数据:摘要算法和解密的摘要(您的内容的原始摘要)

标签: java openssl rsa digital-signature asn.1


【解决方案1】:

OpenSSL-verify命令输出恢复的RSA签名数据

-验证 验证输入数据并输出恢复的数据。

这意味着正在返回 PKCS#1 消息。 RFC2313 之后的数字签名由摘要算法标识符和使用 PKCS#7 格式的 RSA 私钥的内容的加密摘要组成,如 RFC2315 的第 9.1 节所述。

signedData ::= SEQUENCE {
 version Version,
 digestAlgorithms DigestAlgorithmIdentifiers,
 contentInfo ContentInfo,
 certificates
    [0] IMPLICIT ExtendedCertificatesAndCertificates
      OPTIONAL,
 crls
   [1] IMPLICIT CertificateRevocationLists OPTIONAL,
 signerInfos SignerInfos }

所以(如果我理解正确的话......),openssl 的输出是一个 ASN.1 序列的摘要算法 + 解密的摘要(您的内容的原始摘要)

要解码它,你可以使用Bouncycastle

public class ASN1Decoder {
    private static String opensslOutputB64= "MDEwDQYJYIZIAWUDBAIBBQAEIGGbJmsmf9lg/jeaXjm0XsUZ4ZS7xv0Da/NvPoNiRzRO";
    
    public final static void main(String argv[]) throws IOException{
        ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(Base64.getDecoder().decode(opensslOutputB64)));
         ASN1Primitive obj = bIn.readObject();
         System.out.println(ASN1Dump.dumpAsString(obj));
        
    }
}

查看Parsing ASN.1 binary data with Java 了解更多示例

【讨论】:

    【解决方案2】:

    在@pedrofb 的帮助下,我设法提出了以下解决方案:

    // Get key from cert
    CertificateFactory fact = CertificateFactory.getInstance("X.509", new org.bouncycastle.jce.provider.BouncyCastleProvider());
    X509Certificate cer = (X509Certificate) fact.generateCertificate(new FileInputStream("/home/administrator/Downloads/cert_1.txt"));
    PublicKey key = cer.getPublicKey();
    
    // or read key in from pem file
    PublicKey publicKey = ManifestUtils.publicKeyFromPemFile(new FileReader("/home/administrator/Downloads/publickey.txt"));
    
    // Decrypt the signature
    Cipher asymmetricCipher
                = Cipher.getInstance("RSA/ECB/PKCS1Padding", new org.bouncycastle.jce.provider.BouncyCastleProvider());
    asymmetricCipher.init(Cipher.DECRYPT_MODE, publicKey);
    byte[] plainText = asymmetricCipher.doFinal(
                IOUtils.toByteArray(new FileInputStream("/home/administrator/Downloads/signature.sign")));
    
    // print as hex
    System.out.println(Hex.encodeHexString(plainText));
    
    // Print the ans1 nicely - ish
    ASN1InputStream input = new ASN1InputStream(plainText);
    ASN1Primitive p;
    while ((p = input.readObject()) != null) {
        System.out.println(ASN1Dump.dumpAsString(p));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      相关资源
      最近更新 更多