使用PGP公钥在C ++中使用Windows CryptoApi进行加密

时间:2014-12-10 23:04:10

标签: c++ encryption cryptoapi gnupg

我不知道这是否可行。使用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的数据?

谢谢。

1 个答案:

答案 0 :(得分:2)

将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,也可能有其他库这样做。