【问题标题】:Public Key Unknown Encoding公钥未知编码
【发布时间】:2015-11-09 21:32:49
【问题描述】:

我有这个公钥:

MIGJAoGBAKv4OKlpY2oq9QZPMzAjbQfiqDqTnisSvdLP+mTswZJdbtk1J+4+qAySJuZjSQljzcUu0ANg+QG0VsvoU72zu5pErZKWubfe9HB/tq69bhP60qgP6/W2VebWlqUNGtsMedxuVaFBL3SoqU7e5RELIsuArCJJIgz86BQDX0x63VpXAgMBAAE=

我正在尝试用它来解码:

Zm/qR/FrkzawabBZYk7WfQJNMVZoZrwWTvfQwIhPMzAuqEO+y+sb/x9+TZwTbqmu45/GV4yhKv0bbDL8F6rif7RJap7iQUFQBDEIAraY42IGZ8pB6A0Q0RSnJWW+tLTLJg5cTrgZQ8sLoO+U03T6DE1wy73FU5h6XhXxZERo0tQ=

我知道未加密的值是这样的:

2ABB43E83F7EC33D0D33F64BA5782E42

我一直在尝试几种不同的方法,包括 Bouncy Castle(Java 实现),但我无法让公钥工作,主要以无效编码错误告终。

这是我当前的实现:

byte[] keyBytes = Base64.decodeBase64(PUB_KEY);
try {
        AlgorithmIdentifier rsaIdent = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption);
        SubjectPublicKeyInfo kInfo = new SubjectPublicKeyInfo(rsaIdent, keyBytes);
        ASN1Primitive primKey = kInfo.parsePublicKey();
        byte[] encoded = primKey.getEncoded();
        byte[] sessionBytes = Base64.decodeBase64("Zm/qR/FrkzawabBZYk7WfQJNMVZoZrwWTvfQwIhPMzAuqEO+y+sb/x9+TZwTbqmu45/GV4yhKv0bbDL8F6rif7RJap7iQUFQBDEIAraY42IGZ8pB6A0Q0RSnJWW+tLTLJg5cTrgZQ8sLoO+U03T6DE1wy73FU5h6XhXxZERo0tQ=");
        Security.addProvider(new BouncyCastleProvider());
        X509EncodedKeySpec spec = new X509EncodedKeySpec(encoded);
        KeyFactory factory = KeyFactory.getInstance(spec.getFormat());
        Cipher cipher = Cipher.getInstance("RSA", "BC");
        cipher.init(Cipher.DECRYPT_MODE, factory.generatePublic(spec));
        // ----- THIS IS WHERE IT BREAKS -----
        byte[] decrypted = cipher.doFinal(sessionBytes);
        String tada = new String(decrypted, StandardCharsets.UTF_8);
} catch (Exception e) { ... }

当我从工厂生成公钥时,我得到了

 java.lang.IllegalArgumentException: unknown object in getInstance: org.bouncycastle.asn1.ASN1Integer

我尝试了其他几件事,但都导致上述相同的错误。

我的公钥有问题吗?这样做的正确方法是什么?

【问题讨论】:

  • 执行.parsePublicKey 并(重新)编码结果只会让您返回相同的 PKCS#1 密钥。如果您改为使用kInfo.getEncoded(),您将获得整个 SPKI 编码,并且 KeyFactory-X509 可以解析它。因为您的值实际上是一种 PKCS#1 签名未加密,所以 JCE 在 Cipher-RSA/ECB/PKCS1Padding (DECRYPT,RSAPublic) 中提供了所需(但无效)的值。

标签: java cryptography rsa public-key


【解决方案1】:

首先,您的密钥是 PKCS#1 编码的。它不是 Java 所需的 SubjectPublicKeyInfo 结构。你可以看看如何解码它here

其次,你不能用公钥解密,你需要一个私钥。

【讨论】:

  • 对你来说够快了吗,HuXu7?
  • 速度惊人,非常感谢!谢谢!
  • 这里的值实际上是 PKCS#1-type1 (aka RSASSA-PKCS1v1_5) signed 未加密,除了高度可疑的哈希值(所有 ASCII 十六进制数字)并且没有AlgorithmIdentifier,可能是相信“签名是用私钥加密”的常见谎言的人。 JCE 有一个 hack,其中 Cipher 算法 RSA 可以 ENCRYPTRSAPrivateKeyDECRYPTRSAPublicKey 并且它实际上确实签名和恢复。
  • @dave_thompson_085 我认为这是因为 MD5 和 SHA1 的 SSL 签名格式。在这种情况下,仅使用 PKCS#1 未填充进行签名验证,从而导致哈希连接在一起。
  • 未填充的值为32字节; MD5+SHA1 为 36。它可能类似于 MD5+RIPEMDold,但所有八位位组为十六进制数字的概率为 2^-128。我敢打赌,它是一个 128 位哈希,例如 MD5,被不知道自己在做什么的人转换为十六进制(32 个字符),并且出于同样的原因省略了 SEQ-AlgId-OCTSTR。
猜你喜欢
  • 1970-01-01
  • 2015-02-23
  • 2012-06-13
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多