无法使用 SUDS (python) 解密 MTOM/XOP 附件
Unable to decrypt MTOM/XOP attachment using SUDS (python)
我有一个从服务器下载文件的 SOAP 客户端。请求的正文和附件(文件)使用两个单独的密钥加密。这两个键都包含在各自的 <xenc:EncryptedKey>
标签中。我可以使用其中一个密钥毫无问题地解密正文,但是附件给我带来了问题。
我的代码:
from Crypto.Cipher import AES
from Crypto import Random
class AESCipher:
def __init__( self, key, BS = 16):
self.key = key
self.BS = BS
def _pad(self, s):
return s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS)
def _unpad(self, s):
return s[:-ord(s[len(s)-1:])]
def decrypt( self, enc ):
enc = base64.b64decode(enc)
iv = enc[:self.BS]
cipher = AES.new(self.key, AES.MODE_CBC, iv )
return self._unpad(cipher.decrypt( enc[self.BS:]))
with open('test/resp-down-file','rb') as f:
encFile = f.read()
#...the key is extracted elsewhere...
cryptor = AESCipher(key)
cryptor.decrypt(encFile)
充其量我得到的结果是乱码,但通常它只是说 Error while decrypting in CBC mode
。
问题:有人遇到过这个问题吗?我愿意接受 Python、Java、PHP、Perl、C 以及几乎所有在 linux 上运行的建议。
MTOM/XOP 附件的加密方式有什么特别之处吗?
我已经看到 this 个问题,但没有正确答案。 octet/stream 指的是内容类型,而不是传递机制,因此答案不正确。
编辑: 服务器规范说他们使用带有 PKCS5 填充的 AES128-CBC 算法加密消息。他们使用 DES 填充进行 AES 加密对我来说没有意义,但他们坚持这一点。
Edit2: 有时附加信息的长度不适合 AES128 解密(例如 6023 字节或 4071 字节)。
作为参考,消息采用以下格式:
--MIMEBoundaryurn_uuid_641B9D88B371C8A80C1501095406237
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-ID: <0.urn:uuid:641B9D88B371C8A80C1501095406238@apache.org>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
...
</soapenv:Envelope>
--MIMEBoundaryurn_uuid_641B9D88B371C8A80C1501095406237
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <urn:uuid:641B9D88B371C8A80C1501095406240@apache.org>
8eJ¨%• }\ Œ“\ò½<( nË%¸£käö0 ‡XW�5ìR Ë�¾p�Áëş3Âå'¹5¥#=Zg¡øø{I~FP�n ×aµR^Föž¤¥EÍf«Îê�0qÊMö²È€]®PÌ>A@‡ Cş®±9>Áf7P’#ã …fç~yxÔ.å–×v›±Cô„Ê
...
--MIMEBoundaryurn_uuid_641B9D88B371C8A80C1501095406237--
我想通了。事实证明,我接收数据的方式(使用 result = requests.post(....)
修剪了一些不可打印的字符,因为我使用的是 result.text
。
现在我已经切换到 result.raw.read()
并且问题已解决。
我有一个从服务器下载文件的 SOAP 客户端。请求的正文和附件(文件)使用两个单独的密钥加密。这两个键都包含在各自的 <xenc:EncryptedKey>
标签中。我可以使用其中一个密钥毫无问题地解密正文,但是附件给我带来了问题。
我的代码:
from Crypto.Cipher import AES
from Crypto import Random
class AESCipher:
def __init__( self, key, BS = 16):
self.key = key
self.BS = BS
def _pad(self, s):
return s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS)
def _unpad(self, s):
return s[:-ord(s[len(s)-1:])]
def decrypt( self, enc ):
enc = base64.b64decode(enc)
iv = enc[:self.BS]
cipher = AES.new(self.key, AES.MODE_CBC, iv )
return self._unpad(cipher.decrypt( enc[self.BS:]))
with open('test/resp-down-file','rb') as f:
encFile = f.read()
#...the key is extracted elsewhere...
cryptor = AESCipher(key)
cryptor.decrypt(encFile)
充其量我得到的结果是乱码,但通常它只是说 Error while decrypting in CBC mode
。
问题:有人遇到过这个问题吗?我愿意接受 Python、Java、PHP、Perl、C 以及几乎所有在 linux 上运行的建议。
MTOM/XOP 附件的加密方式有什么特别之处吗?
我已经看到 this 个问题,但没有正确答案。 octet/stream 指的是内容类型,而不是传递机制,因此答案不正确。
编辑: 服务器规范说他们使用带有 PKCS5 填充的 AES128-CBC 算法加密消息。他们使用 DES 填充进行 AES 加密对我来说没有意义,但他们坚持这一点。
Edit2: 有时附加信息的长度不适合 AES128 解密(例如 6023 字节或 4071 字节)。
作为参考,消息采用以下格式:
--MIMEBoundaryurn_uuid_641B9D88B371C8A80C1501095406237
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-ID: <0.urn:uuid:641B9D88B371C8A80C1501095406238@apache.org>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
...
</soapenv:Envelope>
--MIMEBoundaryurn_uuid_641B9D88B371C8A80C1501095406237
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <urn:uuid:641B9D88B371C8A80C1501095406240@apache.org>
8eJ¨%• }\ Œ“\ò½<( nË%¸£käö0 ‡XW�5ìR Ë�¾p�Áëş3Âå'¹5¥#=Zg¡øø{I~FP�n ×aµR^Föž¤¥EÍf«Îê�0qÊMö²È€]®PÌ>A@‡ Cş®±9>Áf7P’#ã …fç~yxÔ.å–×v›±Cô„Ê
...
--MIMEBoundaryurn_uuid_641B9D88B371C8A80C1501095406237--
我想通了。事实证明,我接收数据的方式(使用 result = requests.post(....)
修剪了一些不可打印的字符,因为我使用的是 result.text
。
现在我已经切换到 result.raw.read()
并且问题已解决。