我正在尝试使用iOS上的3des加密一些必须与java和.NET的结果相匹配的东西.
public class EncryptionHelper {
// Encrypts string and encode in Base64
public static String encryptText(String plainText,String key, String IV) throws Exception {
// ---- Use specified 3DES key and IV from other source --------------
byte[] plaintext = plainText.getBytes();//input
byte[] tdesKeyData = key.getBytes();// your encryption key
byte[] myIV = IV.getBytes();// initialization vector
Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DESede");
IvParameterSpec ivspec = new IvParameterSpec(myIV);
c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
byte[] cipherText = c3des.doFinal(plaintext);
String encryptedString = Base64.encodetoString(cipherText,
Base64.DEFAULT);
// return Base64Coder.encodeString(new String(cipherText));
return encryptedString;
}
}
和iOS代码相同的是:
-(Nsstring*)new3DESwithoperand:(Nsstring*)plaintext encryptOrDecrypt:(Ccoperation)encryptorDecrypt key:(Nsstring*)key initVec:(Nsstring*)initVec
{
NSData* data = [plaintext dataUsingEncoding:NSUTF8StringEncoding];
const void *vplainText = [data bytes];;
size_t plainTextBufferSize = [data length];
NSLog(@"%@, Length: %u",[data description],[data length]);
size_t bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
NSLog(@"%zu, sizof of uint8_t: %zu",bufferPtrSize, sizeof(uint8_t));
size_t movedBytes = 0;
uint8_t *bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
NSLog(@"%zu",sizeof(bufferPtr));
memset((void*)bufferPtr, 0x0, bufferPtrSize);
NSLog(@"%zu",sizeof(bufferPtr));
const void * vkey = [[NSData base64DataFromString:key] bytes];
const void *vinitVec = [[NSData base64DataFromString:initVec] bytes];
NSLog(@"vinitvec: %@",[[NSData base64DataFromString:initVec] description]);
CCCryptorStatus ccStatus;
ccStatus = CCCrypt(encryptorDecrypt,
kCCAlgorithm3DES,
kCcoptionPKCS7Padding & kCCModeCBC,
vkey,
kCCKeySize3DES,
vinitVec,
vplainText,
plainTextBufferSize,
(void*)bufferPtr,
bufferPtrSize,
&movedBytes);
NSData* result = [NSData dataWithBytes:(const void*)bufferPtr length:(NSUInteger)movedBytes];
Nsstring* str = [Nsstring base64StringFromData:result length:result.length];
NSLog(@"%@",str);
return str;
}
此代码成功加密和解密字符串.但是,它与.NET和java的结果不匹配.
谢谢
解决方法:
已经找到了解决上述在iOS和.NET或Java上生成的加密值问题的解决方案.
解:
1.在Android和.NET中,您必须使用大小为16字节的密钥(例如:key =“1234567890123456”)
在iOS中,您需要使用24字节的密钥大小,但密钥的生成会产生一些差异.
使用与Android或.NET(16字节)中使用的相同的密钥,并将其附加到相同密钥的前8个字节.
key16Byte =“1234567890123456”// Android和.NET密钥
key24Byte = key16Byte“12345678”// ios和Java密钥,复制前8字节16Byte密钥
// new24ByteKey =“123456789012345612345678”
>从CCypher模式中删除“& kCCModeCBC”.
>某些值需要CCCrypt函数中的字节,我已在下面的代码中进行了更改.像keyData,encryptData.
生成不同加密的原因:
Android和.NET – 它需要16Byte密钥并在内部复制,并生成24Byte密钥.
Java – 如果提供16Byte键值,它会抛出异常“无效键长度”.
iOS – 它生成16Byte和24Byte两个值的加密值,而不会抛出任何异常,因此我们在16Byte键的情况下生成不同的加密.
Java代码
public class EncryptionHelper {
// Encrypts string and encode in Base64
public static String encryptText(String plainText,String key, String IV) throws Exception {
// ---- Use specified 3DES key and IV from other source --------------
byte[] plaintext = plainText.getBytes();//input
byte[] tdesKeyData = key.getBytes();// your encryption key
byte[] myIV = IV.getBytes();// initialization vector
Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DESede");
IvParameterSpec ivspec = new IvParameterSpec(myIV);
c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
byte[] cipherText = c3des.doFinal(plaintext);
String encryptedString = Base64.encodetoString(cipherText,
Base64.DEFAULT);
// return Base64Coder.encodeString(new String(cipherText));
return encryptedString;
}
iOS代码:
- (Nsstring *)encrypt:(Nsstring *)encryptValue key:(Nsstring *)key24Byte IV:(Nsstring *)IV{
// first of all we need to prepare key
if([key length] != 24)
return @"Require 24 byte key, call function generate24ByteKeySameAsAndroidDotNet with a 16Byte key same as used in Android and .NET"; //temporary error message
NSData *keyData = [key24Byte dataUsingEncoding:NSUTF8StringEncoding];
// our key is ready, let's prepare other buffers and moved bytes length
NSData *encryptData = [encryptValue dataUsingEncoding:NSUTF8StringEncoding];
size_t resultBufferSize = [encryptData length] + kCCBlockSize3DES;
unsigned char resultBuffer[resultBufferSize];
size_t moved = 0;
// DES-CBC requires an explicit Initialization Vector (IV)
// IV - second half of md5 key
NSMutableData *ivData = [[IV dataUsingEncoding:NSUTF8StringEncoding]mutablecopy];
NSMutableData *iv = [NSMutableData dataWithData:ivData];
CCCryptorStatus cryptorStatus = CCCrypt(kCCEncrypt, kCCAlgorithm3DES,
kCcoptionPKCS7Padding , [keyData bytes],
kCCKeySize3DES, [iv bytes],
[encryptData bytes], [encryptData length],
resultBuffer, resultBufferSize, &moved);
if (cryptorStatus == kCCSuccess) {
return [[NSData dataWithBytes:resultBuffer length:moved] base64EncodedStringWithOptions:0];
} else {
return nil;
}
}
iOS版
-(Nsstring *)generate24ByteKeySameAsAndroidDotNet:(Nsstring *)key{
Nsstring *new24ByteKey = key;
;
new24ByteKey = [new24ByteKey stringByAppendingString:[key substringWithRange:NSMakeRange(0, 8)]];
return new24ByteKey;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。