OpenSSL CMS在C++和Objective-C中进行加密

OpenSSL CMS encrypt in C++ and Objective-c

本文关键字:加密 Objective-C CMS C++ OpenSSL      更新时间:2023-10-16

我正在使用OpenSSL的CMS库加密文本(只是一个字符串)。我已经实现了一个cms加密方法,当我在C++项目中调用它时(使用相同的证书和输入字符串),它会产生以下输出:

MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"
Content-Transfer-Encoding: base64
MIAGCSqGSIb3DQEHA6CAMIACAQAxggG9MIIBuQIBADCBoDCBkjELMAkGA1UEBhMC
QVQxDzANBgNVBAgMBlN0eXJpYTENMAsGA1UEBwwER3JhejEKMAgGA1UECgwBLzEK
MAgGA1UECwwBLzEdMBsGA1UEAwwUQ2hyaXN0b2YgU3Ryb21iZXJnZXIxLDAqBgkq
hkiG9w0BCQEWHXN0cm9tYmVyZ2VyQHN0dWRlbnQudHVncmF6LmF0AgkAmHFnJtIY
YyAwDQYJKoZIhvcNAQEBBQAEggEACLskYA0ma3hBccwOamh14/b2XqRCmBakGxPM
dQFMoiQy47UvGLQ4QmruOU1Mv530r3jglxVZd2DNX5fBPwHJ91ORU39BGns2BnWd
E5z8yH5Kr1edjErj/EZRzJFU1Qyq6/uBn3W4X9+jNhuWWcPrxoQOoQhrE0vETnv4
dZb5ic1iYLWOraSwnQmvOLgrh9iCJuq6n9EWF/YHJelETKQSO2RnPvbpesHLgZ48
ngGkDH+FWU0QZV+LXmq8xpdpLWxMAeh07WIUz0sA1okYFMCk2uy5sg7ovyO804ae
AbZlXz8aDeoMMGzOfNi2PxYxbwRwObBOj2cxU0qMQu49lgIhJjCABgkqhkiG9w0B
BwEwFAYIKoZIhvcNAwcECNUojhuQn568oIAEGPkzqWrziObAHieBNpIKMGboxxY8
oiTMIAQIToaGyI0IMGcAAAAAAAAAAAAA

但是,当我将代码复制到objective-c项目(对于iOS5)中时,我得到了一个"错误"的输出,我无法再解密。。。这是输出:

MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"
Content-Transfer-Encoding: base64
MIAGCSqGSIb3DQEHA6CAMIACAQAxggG4MIIBtAIBADCBoDCBkjELMAkGA1UEBhMC
QVQxDzANBgNVBAgMBlN0eXJpYTENMAsGA1UEBwwER3JhejEKMAgGA1UECgwBLzEK
MAgGA1UECwwBLzEdMBsGA1UEAwwUQ2hyaXN0b2YgU3Ryb21iZXJnZXIxLDAqBgkq
hkiG9w0BCQEWHXN0cm9tYmVyZ2VyQHN0dWRlbnQudHVncmF6LmF0AgkAmHFnJtIY
YyAwDQYJKoZIhvcNAQEBBQAEgfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwgAYJKoZIhvcNAQcBMBQG
CCqGSIb3DQMHBAgAyfDfER+rUaCABBi7ammjNh3zr0CZDxRjalXcmxC5qIbWsoUE
COCbSOGWOGcWAAAAAAAAAAAAAA==

它是完全相同的代码,但产生两个不同的输出。对我来说,第二个输出似乎很奇怪,因为base64编码中有一个鬃毛"AAAA"。我想这一定是证书的一部分。底部是加密的输入字符串,证书的开头是相等的,但在证书的中间或结尾会发生奇怪的变化。

有人有什么建议吗?

S/MIME编码通常如下所示:
  1. 生成随机密钥
  2. 使用该随机密钥和对称密码(例如AES或三重DES)加密明文
  3. 使用收件人的公钥和非对称密码(例如RSA)加密随机密钥

您可以使用类似"opensslasn1parse"的命令来更好地了解这些消息的内部结构,例如:

$ openssl asn1parse < blah.txt

其中blah.txt包含S/MIME输出,减去MIME头(即以"MIAGCSq…"开头)

...
  196:d=6  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  207:d=6  hl=2 l=   0 prim: NULL              
  209:d=5  hl=4 l= 256 prim: OCTET STRING      [HEX DUMP]:08BB24600D266B784171CC0E6A6875E3F6F65EA4429816A41B13CC75014CA22432E3B52F18B438426AEE394D4CBF9DF4AF78E09715597760CD5F97C13F01C9F75391537F411A7B3606759D139CFCC87E4AAF579D8C4AE3FC4651CC9154D50CAAEBFB819F75B85FDFA3361B9659C3EBC6840EA1086B134BC44E7BF87596F989CD6260B58EADA4B09D09AF38B82B87D88226EABA9FD11617F60725E9444CA4123B64673EF6E97AC1CB819E3C9E01A40C7F85594D10655F8B5E6ABCC697692D6C4C01E874ED6214CF4B00D6891814C0A4DAECB9B20EE8BF23BCD3869E01B6655F3F1A0DEA0C306CCE7CD8B63F16316F047039B04E8F6731534A8C42EE3D96022126
  469:d=3  hl=2 l=inf  cons: SEQUENCE          
  471:d=4  hl=2 l=   9 prim: OBJECT            :pkcs7-data
  482:d=4  hl=2 l=  20 cons: SEQUENCE          
  484:d=5  hl=2 l=   8 prim: OBJECT            :des-ede3-cbc
  494:d=5  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:D5288E1B909F9EBC
  504:d=4  hl=2 l=inf  cons: cont [ 0 ]        
  506:d=5  hl=2 l=  24 prim: OCTET STRING      [HEX DUMP]:F933A96AF388E6C01E278136920A3066E8C7163CA224CC20
  532:d=5  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:4E8686C88D083067
...

来自您的良好输出,以及:

...
  196:d=6  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  207:d=6  hl=2 l=   0 prim: NULL              
  209:d=5  hl=3 l= 252 prim: OCTET STRING      [HEX DUMP]:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
  464:d=3  hl=2 l=inf  cons: SEQUENCE          
  466:d=4  hl=2 l=   9 prim: OBJECT            :pkcs7-data
  477:d=4  hl=2 l=  20 cons: SEQUENCE          
  479:d=5  hl=2 l=   8 prim: OBJECT            :des-ede3-cbc
  489:d=5  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:00C9F0DF111FAB51
  499:d=4  hl=2 l=inf  cons: cont [ 0 ]        
  501:d=5  hl=2 l=  24 prim: OCTET STRING      [HEX DUMP]:BB6A69A3361DF3AF40990F14636A55DC9B10B9A886D6B285
  527:d=5  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:E09B48E196386716
...

关于你糟糕的输出。因此,这表明输出中的所有"A"都应该是RSA加密的密钥,因此RSA加密以某种方式失败了。

如果不了解更多关于代码的信息,就很难说到底出了什么问题。在黑暗中,我想说的是,确保你记得调用OpenSSL_add_all_algorithms()(或实现相同目的的东西),但你可能已经调用了,否则你的代码可能会在任何地方失败,不仅仅是在iOS上。。。

好的。。。问题是OpenSSL库中的一个错误。为某个体系结构(即i386)编译并在x64环境中使用时,CMS_encrypt()方法会产生上述错误输出。这个错误是由汇编程序中的一些性能优化引起的。

有关更多信息,请参阅:http://www.openssl.org/support/faq.cgi=>12。为什么OpenBSD-i386在des-586.s上以"未实现的段类型"构建失败

我通过编译具有no-asm属性的OpenSSL解决了这个问题。./Configure ... no-asm

我遇到这个问题是因为用于iOS模拟器的库需要i386架构,但Mac OSX使用x64。只需用no-asm编译它就可以了。