Dav*_*vid 1 encryption android
我正在尝试在Android上实现AES128算法,我已经引用了这个链接用于基本的AES实现(http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html).
问题是,对于我的项目,密钥是预定义的,它是36字节,而不是16/24/32字节.所以我总是得到"密钥长度不是128/194/256位"的例外.我尝试了iphone sdk的解决方案(参见此链接:iOS加密框架),即使我传递36字节预定义密钥也能正常工作.由于我找不到Apple发布的BlockCipher.c/CommonCryptor.c的实现细节,任何正文都可以帮我弄清楚他们如何从36个字节中选择16个字节?
谢谢.
-----------------------------------更新9月13日------------ ------------------------为了避免混淆,我提供了一些样本和我的进展.我更改了一些保密的数据,但长度和格式保持不变.为节省时间,我只透露核心功能.没有对代码的评论,因为我认为代码是自我解释的.
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;
Run Code Online (Sandbox Code Playgroud)
[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个字节作为新密钥,其他部分保持不变,并且工作中!!!到目前为止,我解决了密钥长度问题.
但是Android版本的输出与iOS版本不同,用于一些长文本,例如30或40字节.我的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;
Run Code Online (Sandbox Code Playgroud)
Base64来自org.apache.commons.codec.binary.Base64.问题是什么?或者c/c ++库上可以做同样事情的任何提示?我也可以将它导入到android中.
剩下的差异(假设您只使用了密钥的前16个字节)是密码流模式.iOS代码使用CBC模式,初始化设置为全零.然而,Android代码使用ECB.
所以正确的Java/Android代码是:
// convert key to bytes
byte[] keyBytes = key.getBytes("UTF-8");
// Use the first 16 bytes (or even less if key is shorter)
byte[] keyBytes16 = new byte[16];
System.arraycopy(keyBytes, 0, keyBytes16, 0, Math.min(keyBytes.length, 16));
// convert plain text to bytes
byte[] plainBytes = plainText.getBytes("UTF-8");
// setup cipher
SecretKeySpec skeySpec = new SecretKeySpec(keyBytes16, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = new byte[16]; // initialization vector with all 0
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(iv));
// encrypt
byte[] encrypted = cipher.doFinal(plainBytes);
Run Code Online (Sandbox Code Playgroud)
我用大约100个字节的数据测试了它,并在iOS和Java上获得了完全相同的结果.
| 归档时间: |
|
| 查看次数: |
7138 次 |
| 最近记录: |