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 解密的主要内容,如果未能解决你的问题,请参考以下文章

使用 Java 解密 AES256 CBC

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 可以

AES在线加密解密-附AES128,192,256,CBC,CFB,ECB,OFB,PCBC各种加密解密源码

ASP中的AES256加解密