由cryptopp创建的DER编码公钥与openssl不同

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了由cryptopp创建的DER编码公钥与openssl不同相关的知识,希望对你有一定的参考价值。

我一直在尝试使用RSA私钥创建DER编码的公钥。我通常创建它的方式是使用命令行:

openssl rsa -pubout -outform DER -in ~/.keys/api_key.pem -out der_pub.der

当我使用CryptoPP创建此文件时,它们略有不同。它似乎有一个额外的部分。 openssl创建的那个有一点额外的部分。我假设这是CryptoPP API中提到的BIT STRING。 https://www.cryptopp.com/docs/ref/class_r_s_a_function.html

void    DEREncodePublicKey (BufferedTransformation &bt) const
encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header 

这就是我的代码:

    ...
    CryptoPP::RSA::PrivateKey rsaPrivate;
    rsaPrivate.BERDecodePrivateKey(queue, false /*paramsPresent*/, queue.MaxRetrievable());

    CryptoPP::ByteQueue bq;
    rsaPrivate.DEREncodePublicKey(bq);
    CryptoPP::FileSink fs1("cryptopp_pub.der", true);
    bq.TransferTo(fs1);
答案

CryptoPP::RSA::DEREncodePublicKey编码subjectPublicKey的subjectPublicKey部分,没有BIT STRING标题

试试CryptoPP::RSA::PublicKey::DEREncode。小心将此应用于公钥,因为RSA :: PrivateKey会重载DEREncode方法。

我在这里使用CryptoPP 8.2

  1. 从磁盘加载DER编码的私钥 CryptoPP::RSA::PrivateKey private_key; { CryptoPP::FileSource file{"my.key", true}; private_key.BERDecodePrivateKey(file, false, -1); }
  2. 保存DER编码的公钥 CryptoPP::FileSink sink{"my.pub", true}; CryptoPP::RSA::PublicKey{private_key}.DEREncode(sink);

OpenSSL的:

# generate a new RSA private key (DER format)
openssl genrsa | openssl rsa -outform DER -out my.key

# hash/fingerprint the public key
openssl rsa -in my.key -inform DER -pubout -outform DER | openssl sha256
writing RSA key
362945ad4a5f87f27d3db3b4adbacaee0ebc3f778ee2fe76ef4fb09933148372

# compare against hash of our code sample's generated public key
cat my.pub | openssl sha256
362945ad4a5f87f27d3db3b4adbacaee0ebc3f778ee2fe76ef4fb09933148372

另一个例子;如果我们想让CryptoPP生成SHA256指纹:

std::string hash_out_str;
{
    CryptoPP::SHA256 sha256;
    CryptoPP::HashFilter filter{
        sha256,
        new CryptoPP::HexEncoder{
            new CryptoPP::StringSink{hash_out_str}
        }
    };
    CryptoPP::RSA::PublicKey{private_key}.DEREncode(filter); // intentionally slice to ensure we aren't exposing a public key
    filter.MessageEnd();
}
std::cout << hash_out_str << '
';

输出:

362945AD4A5F87F27D3DB3B4ADBACAEE0EBC3F778EE2FE76EF4FB09933148372

即,我们需要复制/切片到RSA :: PublicKey以调用OpenSSL兼容的DER编码方法

以上是关于由cryptopp创建的DER编码公钥与openssl不同的主要内容,如果未能解决你的问题,请参考以下文章

如何从存储在 iOS 钥匙串中的密钥中获取 DER 格式的公钥?

数字证书

pfx文件是不是包含根证书

是否有带有点压缩的公钥初始化 API?

从 X.509 证书中提取 PEM 公钥

java 证书 .cer 和 .pfx