【发布时间】:2011-09-12 01:17:56
【问题描述】:
我正在尝试在 Android 上实现 AES128 算法,并且我参考了此链接以了解基本的 AES 实现 (http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html)。
问题是,对于我的项目,密钥是预定义的,它是 36 字节,而不是 16/24/32 字节。所以我总是遇到“密钥长度不是 128/194/256 位”异常。我尝试了来自 iphone sdk 的解决方案(请参阅此链接:The iOS encryption framework),即使我传递了 36 字节的预定义密钥,它也能正常工作。由于我找不到 Apple 发布的 BlockCipher.c/CommonCryptor.c 的实现细节,谁能帮我弄清楚他们是如何从 36 字节中选择 16 字节的?
谢谢。
-----------------------9 月 13 日更新--------- -------------------------- 为了避免混淆,我提供了一些示例和我的进度。我更改了一些机密数据,但长度和格式保持不变。为了节省时间,我只透露核心功能。代码没有 cmets,因为我认为代码已经足够自我解释了。
iOS 示例:
NSString * _key = @"some 36 byte key";
StringEncryption *crypto = [[[StringEncryption alloc] init] autorelease];
NSData *_inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
CCOptions padding = kCCOptionPKCS7Padding;
NSData *encryptedData = [crypto encrypt:_inputData key:[_key dataUsingEncoding:NSUTF8StringEncoding] padding:&padding];
NSString *encryptedString = [encryptedData base64EncodingWithLineLength:0];
return encryptedString;
[crypto encrypt] 实现与我上面提到的链接完全相同。它以加密模式调用 doCipher。核心函数包括 CCCryptorCreate、CCCryptorUpdate 和 CCCryptorFinal,它们来自 . CCCryptorCreate 处理密钥长度。它传递原始密钥字节,并传递一个整数 16 (kCCKeySizeAES128) 作为密钥大小并执行此操作。调用层次结构类似于 CCCryptorCreate/CommonCryptor.c => ccBlockCipherCallouts->CCBlockCipherInit/BlockCipher.c => ccAlgInfo->setkey/BlockCipher.c 。 setkey 实际上是一个指向函数的指针,对于 AES 它指向 aes_cc_set_key。而且我找不到 aes_cc_set_key 实现,在这里迷路了。
----------------------------------------9 月 13 日更新 ---- ------------------------- 我更改了iOS示例代码中的_key,手动将前16个字节作为新密钥,其他部分保持不变,并且可以正常工作!!!至此,我解决了密钥长度问题。
但是对于一些长的纯文本,例如 30 或 40 字节,Android 版本的输出与 iOS 版本不同。我的java实现如下:
String key = "some 16 byte key";
byte[] keyBytes = key.getBytes("UTF-8");
byte[] plainBytes = plainText.getBytes("UTF-8");
SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(plainBytes);
String result = Base64.encodeBytes(encrypted);
return result;
Base64 来自 org.apache.commons.codec.binary.Base64。问题是什么?或者关于可以做同样事情的 c/c++ 库的任何提示?我也可以将它导入到android中。
【问题讨论】:
-
您的加密是否需要产生与在其他系统上实现相同的结果?如果是,那么您将需要有关该信息的更多信息,以便您可以将密钥减少到 16 个字节。 (iPhone 是否产生与参考实现相同的结果?)如果没有,那么您可以自己减少密钥,例如通过将前 16 个字节与接下来的 16 个字节和最后 4 个字节进行异或(用 0 扩展为 16 个字节)。
-
其实这个app是有iOS版本的,我需要在iOS版本的基础上实现android版本。是的,我的实现需要产生与 iOS 实现相同的结果。由于它是客户端-服务器结构,所以其他人实现了服务器部分,包括解密部分,并提供了接口。 iOS 版本完美运行,我测试了服务器返回 HeaderDecryption Error 除非 android 版本输出与指定纯文本的 iOS 输出相同的密文。我将更新问题以使其更详细。
-
看看这个问题以及我和 iOS 的答案:stackoverflow.com/questions/17535918/…
标签: android encryption