【问题标题】:Use PGP public key to cipher with Windows CryptoApi in C++使用 PGP 公钥在 C++ 中使用 Windows CryptoApi 进行加密
【发布时间】:2015-02-09 07:48:12
【问题描述】:

我不知道这是否可能。使用 GNUPG 生成一对 RSA 密钥,并将公钥导出到文件中。我的程序接收到这样的文件,然后它必须使用该文件中的公共 RSA 密钥加密一些数据。该程序是用 C/C++ 编写的,它不会使用外部库,所以我只能使用 Windows CryptoApi 函数(CryptStringToBinary、CryptDecodeObjectEx、CryptImportPublicKeyInfo 等)。

此方法适用于以 base64 编码的 PEM 格式的公共 2048 位 RSA 密钥:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnCEy2jOlwK8qVxAHddaD
J6u8u/D0h8nOexco6Xg8iu7DnZOrKPL/1pTL1pwH5GLp0bsb/NfkxetijIb/C4h7
37y6bZPC8V+Koi2jz2lNCNOF4jWuD9Dw8mYnOeH+HpVkKTDVry824i2+qihWM1s/
DwVNUh4C50asnFl64Qd9ycbE3jDr4+yzeBDC7Pirm21OFVUZhTzNzuT5UQzGidvw
2pomYnDM6NOwoIyrBOP0J4CCGbJnZMsf+Dsya/t9tR0cKgFl1Zh0W/V1eJ8Ud7Yq
vIwGeStNeIcjoVkPGh4Hu1Uj0YHXZeTyy4LYo8OUWIipQEJ/dL4TLd0/uD8cr1LR
TwIDAQAB
-----END PUBLIC KEY-----

但是用 GPG 导出的密钥看起来很不一样:

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2

mQENBFSIwoUBCACpyzbyoFLtg8uPMOVl0a4oRdfSSyyNpVuZiDENvj60JINSLhQq
gkyfRW6KbSxp9rEPjsUWnjEVcZ8EYcTZjalGajaG090WrAM0iop4zagKSK3EjpTO
sdkA0wtX7abeK+s9WBiC4hbFk2Ds6iRHtVCU5zsYzZ2S/lD7+PA6UXjFYSpNpCGr
XjyATh7tiYelFjij7ocgK9MWCCDPv6ti9yRVqmsBJPqIqIfvjyyLxFncSOCAc4+E
2cLFUsDr5rGYZF8OsJ0AICxAWwJn50IXpEpuQVQNAOd5yZsrRj4tOJ6qCo/bL24a
UkzF9+zDkFQ6kPSKqUnpOx7wdby5625eBImTABEBAAG0ImdudXBnX2tleXMgPGdu
dXBna2V5c0B5b3BtYWlsLmNvbT6JATkEEwECACMFAlSIwoUCGwMHCwkIBwMCAQYV
CAIJCgsEFgIDAQIeAQIXgAAKCRD3/5Jn+Ps9o7JfCACfQqOVorlkcpya/N9uT/L0
2RA3Y2CwlMEdCpzxUtlEC9KlcAWEMBYfS68Cvq550VKKA+bz9v1XBta1rGPN5T/4
o8lxa7fEhQYCRcUJ4qBzHHOPJoLd7oYDNjGcMS0LNmt7L8Apm2+WguwufO1x61OA
bfOsxCzPt7kl/PjzQMLeNY3F03SuzgtkSQwDc0CpBgoRYhlbCyorxEuTIdRioZiL
h6G/Wvp4Me9prQiMpEqPkHHhp61+LKdAGKjaCcyOwDUB3Ec1GtY1CRKb3/VRveXQ
nN8hm9+VnbqVBy6HurMsz5rEM9rKbIWl1i2A3CFY4EKbJBcYdiGTB16p/QJ+Ll0o
uQENBFSIwoUBCACfH0Up/2Zf+WwH70Tk4WVmaEMNhEiiN1ivYsPT1RYSgSzsgRzx
LgD9CTWCFl9jf6Ko2YCHujZimTpx4Bd2hGNj07zF8VWl2fpW8nA964HkWg1isk5s
XYiSYRSG6foH6tn8D42fYsJad0A4yZo1P5OoPzql9MTJpH1nVjaWnxTOTRgoYmMo
mPW7DimIDnoKRp/A7yCdw3HiUogKqRedqWTxLzs2odhx1NKDx9A3lA81UQtNSA78
o6h1JGPQUHUU5yl3+EgntDL+qmcx4fW2J/PQ2ingIq+VueeDpUKYNomGcrvR7vvR
EAIUCD9UbQTos3xgzUAa6TZY+sLC/x6lTpq9ABEBAAGJAR8EGAECAAkFAlSIwoUC
GwwACgkQ9/+SZ/j7PaPd0gf/TNqUmBgQQaY+kgfUL2rCauNkBZboku59pNxJu6iJ
W+IEMYLbRg8qzIVS1ui9zxMY8pper88QX82jfZ27Xo5nbct9ZZCjDeWZRX5xJULx
CsK2fHlMA/CdvGZJdm5KMNmVFni+vVJlLzpij5eQ52j+8NvHAPFgL3NlcmdwWVhy
/y3XjG687bB+DnVhlfOb7JijA/WHThjXS6AFH659jlt/Z1FRti6O3cxEJSTN0rQU
bCXkjJPsqQNgEbsBDQ3f6hwZKnpqpQZt417qRahb/LrfIgxAJhiWLyFFWKp3XuX3
mR0t01lrPzIXTQMaY9lce3G3XSoQx+1gu29fBm/rkHvQIQ==
=R8UZ
-----END PGP PUBLIC KEY BLOCK-----

虽然它也是一个 2048 位密钥。如果我修剪空白行和标题,CryptStringToBinary 成功并将其转换为二进制格式,但 CryptDecodeObjectEx 失败(GetLastError() 返回 0x8009310B)。删除校验和也不起作用。

我在这里有点迷路了,基本上,有没有办法获得一个用 GPG 导出的 RSA 公钥,并用它来用 Windows CryptoApi 加密数据?

谢谢。

【问题讨论】:

  • OpenPGP 不仅对密钥使用自己的格式,而且对加密内容也使用自己的格式。如果您尝试以使收件人能够使用 GnuPG 解密的方式进行加密,您将无法使用 Windows Crypto API 进行解密。只是为了确保您意识到这一点。
  • 好吧,我怀疑过,但不太确定。那么,是否有任何开源 C/C++ 库可用于使用 OpenPGP 公钥进行加密?谢谢。
  • 我添加了这个作为答案。

标签: c++ encryption cryptoapi gnupg


【解决方案1】:

将 OpenPGP 密钥转换为 PEM

可以从 OpenPGP 密钥中提取 RSA 公钥并将其转换为 PEM 格式。 Sysmisc has an article about converting to and from OpenPGP keys in different ways。对于 OpenPGP 到 PEM 的方式,归结为:

gpgsm -o  secret-gpg-key.p12 --export-secret-key-p12 0xXXXXXXXX
openssl pkcs12 -in secret-gpg-key.p12 -nokeys -out gpg-certs.pem

OpenPGP 有自己的消息交换格式

但需要注意的是,如果您想对 OpenPGP 用户进行加密,他将无法使用像 GnuPG 这样的 OpenPGP 实现来读取任何(Open,...)SSL 加密信息。 OpenPGP 不仅使用了不同的密钥格式,还使用了另一种消息交换格式。

如果您想发送 OpenPGP 消息,请使用 GPGME 从 C 接口 GnuPG,可能还有其他库可以这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-13
    • 2012-05-06
    • 2019-03-26
    • 2011-10-22
    • 2012-05-25
    • 1970-01-01
    • 2013-03-20
    • 2011-08-16
    相关资源
    最近更新 更多