iOS AES256 解密
Posted
技术标签:
【中文标题】iOS AES256 解密【英文标题】:iOS AES256 decryption 【发布时间】:2014-08-01 20:10:19 【问题描述】:我需要解密一个用 AES256 加密的字符串。
例如: 这是一个加密字符串: "U2FsdGVkX18egiyzJUY5gHS++2trNSYNSEXpJicKPBE=" 使用这个键: “70ca7c5b0f58ca290d39613fa3644251” 使用 AES256 算法
示例字符串已使用以下方法加密:
https://code.google.com/p/crypto-js/
有多种工具可用于解密 AES256 加密字符串: https://github.com/AlanQuatermain/aqtoolkit/tree/master/CommonCrypto
https://github.com/RNCryptor/RNCryptor
https://github.com/Gurpartap/AESCrypt-ObjC
我已经尝试了所有方法,但没有一个能够解密我的字符串。 我确定它已正确加密,因为我可以使用此在线工具对其进行解密:
http://www.appcove.com/tool/aes
请帮帮我。
谢谢你, 乔治
----------- 编辑 --------------
你能推荐一个 API(js)/ios 的对称加密/解密算法吗? 用于加密 API 上的字符串并在 iOS 应用上解密它们的东西。
谢谢
【问题讨论】:
首先注意加密后的字符串是Base64编码的。必须匹配的参数是 key、iv(如果是 CBC 模式)、padding。加密是二进制字节操作,任何 Base64 或其他编码都不是加密的一部分。未指定模式和可能的 iv 和填充(如果有)。解密后的字符串是“老师”吗? 如果模式为ECB且有PKCS7填充,iOS中如何解密字符串? 【参考方案1】:让您开始:
This is an encrypted string: "U2FsdGVkX18egiyzJUY5gHS++2trNSYNSEXpJicKPBE="
这不是加密字符串。它是加密字节数组的 Base64 渲染。为了解密它,您首先需要将它从 Base64 转换回字节数组。
using this key: "70ca7c5b0f58ca290d39613fa3644251"
这不是钥匙。它是字节数组的十六进制字符串表示形式,既可以是实际密钥,也可以用于派生实际密钥。您需要将其从十六进制字符串转换回字节数组。
with the AES256 algorithm
您需要更多信息:至少是模式和填充。
正在使用什么模式? AES-ECB、AES-CBC、AES-CTR 还是其他模式?查看描述以尝试找出答案。正如 Zaph 的评论所说,缺少 IV 或 Nonce 可能表明欧洲央行模式。 ECB 模式不安全,请不要将其用于任何生产代码。
您还需要知道使用了哪些填充。 Zaph 说 PKCS7 填充,这很常见,但问题来源应该已经告诉你了。您需要设置解密方法以期望正确的填充。
【讨论】:
【参考方案2】:我会给你一个简单的流程来展示 AES 的工作原理:
为了清楚起见,我将使用 pseudo-objective-c 让你既可以理解又可以快速。
// Here comes encryption process:
NSString *key = @"fsd7f897sfd8sfds…";
NSString *secretMessage = @"Confidential text";
AES *aes = [AES sharedAES];
NSString *encryptedMessage = [aes encryptWithKey:key message:secretMessage];
// Now is time for decryption:
Base64 *base64 = [Base64 sharedBase64];
NSString *messageToDecrypt = [base64 decode:encryptedMessage];
NSString *decryptedMesage = [aes decryptWithKey:key message:messageToDecrypt];
// Now you should have the result:
NSLog(decryptedMesage);
看看http://travistidwell.com/jsencrypt/
【讨论】:
我没有密钥和私钥。 “decryptWithPrivateKey”和“encryptWithPublicKey”你用的是什么? @Zaph 误认为 RSA,已修复。乔治,你应该有密钥来加密和解密你的消息。 以下是我如何使用带有显式密钥的 JSEncrypt:gist.github.com/KamilLelonek/9108495。也许这个库会更好考虑? 以Salted__
开头的密文通常由OpenSSL生成。【参考方案3】:
来自谷歌文档:
对于密钥,当您传递一个字符串时,它会被视为密码,并且 用于派生实际密钥和 IV。或者你可以传递一个 WordArray 表示实际的密钥。如果您传递实际密钥,您还必须 通过实际的IV。
对于CryptoJS.AES.encrypt()
是否将一个字符串作为密钥传入,另一个密钥将被派生,也是一个 iv。这将是一个兼容性问题,因为在 iOS 中必须知道实际密钥派生的方法以及 iv 派生和复制。
以上都不是标准。
解决方案是在 javascript 中将密钥作为正确大小(256 位)的 WordArray 和 WordArray iv 传递。
或根据文档:
"您可以定义自己的格式以便与其他格式兼容 加密实现。格式是具有两个的对象 方法——字符串化和解析——在 CipherParams 对象之间进行转换 和密文字符串。
然后在iOS中可以匹配相同的加密/解密。
这是我想出来的一些信息,这是WRT base64编码之前的加密数据:
前8个字节为“Salted__” 可能是Javascript解密使用的,知道使用方法。 接下来的 8 个字节是随机的。对于使用相同密钥的相同数据的每次加密,它们是不同的。它们可能是从具有随机分量的密钥中派生的。 接下来的字节以 16 个字节为一组(块大小),刚好足以包含数据 + 填充。填充总是至少增加一个额外的字节。
由于 iv 是随机的,对于使用 相同数据和密钥的每次加密,加密的字节将不同,但可以通过以某种方式恢复使用密钥和前导字节重新生成密钥和 iv。方法不是秘密,只是我不知道。
当然,这并没有特别的帮助,但确实显示了问题。
【讨论】:
以上是关于iOS AES256 解密的主要内容,如果未能解决你的问题,请参考以下文章
AES (aes-cbc-128, aes-cbc-192, aes-cbc-256) 使用 openssl C 加密/解密
python Crypto AES-256-ECB 与PHP之间完成加解密
无法使用来自 AES-256-CBC 的 pgcrypto 解密,但 AES-128-CBC 可以