任何人都可以告诉我为什么 iOS 中的 3des 每次在 iOS 中加载时都会产生不同的编码字符串? 最初,我将"key"转换为 MD5 格式的字符串,然后在 3des 中使用相同的键来生成编码值。
这是我的代码:
-(NSData *)tripleDesEncryptString:(NSString *)input key:(NSString* )key error:(NSError **)error{
//TDES
NSParameterAssert(input);
NSParameterAssert(key);
NSData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
size_t outLength;
//NSAssert(keyData.length == kCCKeySize3DES, @"the keyData is an invalid size");
NSMutableData *outputData = [NSMutableData dataWithLength:(inputData.length + kCCBlockSize3DES)];
CCCryptorStatus result = CCCrypt(
kCCEncrypt, // operation
kCCAlgorithm3DES, // Algorithm
kCCOptionECBMode | kCCOptionPKCS7Padding, // options
keyData.bytes, // key
keyData.length, // keylength
nil, // iv
inputData.bytes, // dataIn
inputData.length, // dataInLength,
outputData.mutableBytes, // dataOut
outputData.length, // dataOutAvailable
&outLength // dataOutMoved
);
if (result != kCCSuccess) {
if (error != NULL) {
*error = [NSError errorWithDomain:@"com.your_domain.your_project_name.your_class_name." code:result userInfo:nil];
}
return nil;
}
[outputData setLength:outLength];
return outputData;
}
-(void) testEncryptionAndDecryption {
NSString *str =@"ker!@#$%^&*()";
id md5data =[str MD5];
NSString *md5dataString =(NSString *)md5data;
NSData *encrypted = [self tripleDesEncryptString:@"abcdef@dd.com:123" key:md5dataString error:nil];
NSString *strData = [encrypted base64EncodedStringWithOptions:0];
NSLog(@"encrypted data length: %@",strData);
NSString *str2 = [[NSString alloc] initWithData:encrypted encoding:NSUTF8StringEncoding];
NSLog(@"%@",str2);
}
测试代码有缺陷。
NSString *str =@"ker!@#$%^&*()";
id md5data =[str MD5];
NSString *md5dataString =(NSString *)md5data;
目前还不清楚MD5
是什么,可能是一个类别?
MD5
函数生成 16 字节结果,但 3DES 需要 24 字节密钥。
NSString *str2 = [[NSString alloc] initWithData:encrypted encoding:NSUTF8StringEncoding];
将失败,因为任意数据可以机器人表示为字符串。这就是使用 Base64 的原因。
实际上,最好编写一个加密方法,该方法获取并返回NSData
参数,并在它之外执行任何字符串操作。这就产生了单一责任方法。
这是一个重构的版本 - 但仍然不安全:
-(NSData *)tripleDesEncryptData:(NSData *)data
key:(NSData* )key
error:(NSError **)error {
NSParameterAssert(data);
NSParameterAssert(key);
NSAssert(key.length == kCCKeySize3DES, @"the keyData is an invalid size");
size_t outLength;
NSMutableData *outputData = [NSMutableData dataWithLength:(data.length + kCCBlockSize3DES)];
CCCryptorStatus
result = CCCrypt(kCCEncrypt, // operation
kCCAlgorithm3DES, // Algorithm
kCCOptionECBMode | kCCOptionPKCS7Padding , // options
key.bytes, // key
key.length, // keylength
nil,// iv
data.bytes, // dataIn
data.length, // dataInLength,
outputData.mutableBytes, // dataOut
outputData.length, // dataOutAvailable
&outLength); // dataOutMoved
if (result != kCCSuccess) {
if (error != NULL) {
*error = [NSError errorWithDomain:@"com.your_domain.your_project_name.your_class_name."
code:result
userInfo:nil];
}
return nil;
}
[outputData setLength:outLength];
return outputData;
}
- (NSData *)hash192String:(NSString *)inputString {
NSData *inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *hash = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
CC_SHA256(inputData.bytes, (unsigned int)inputData.length, hash.mutableBytes);
return [hash subdataWithRange:NSMakeRange(0, 24)];
}
-(void) testEncryptionAndDecryption {
NSString *md5String = @"ker!@#$%^&*()";
NSString *stringData = @"abcdef@dd.com:123";
NSData *keyData = [self hash192String:md5String];
NSData *data = [stringData dataUsingEncoding:NSUTF8StringEncoding];
NSData *encrypted = [self tripleDesEncryptData:data key:keyData error:nil];
NSString *encryptedBase64 = [encrypted base64EncodedStringWithOptions:0];
NSLog(@"encrypted base64nlength: %lunstring: %@", (unsigned long)encryptedBase64.length, encryptedBase64);
}
输出:
加密底座64
长度: 32
string: +VSdzF4BmAMnGITAWFqaY2mgp8Nr8I13
func testCrypt(data:NSData, keyData:NSData, ivData:NSData) -> String {
var base64cryptString = String()
let cryptData = NSMutableData(length: Int(data.length) + kCCBlockSizeAES128)!
let keyLength = size_t(kCCKeySizeAES128)
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
keyData.bytes, keyLength,
ivData.bytes,
data.bytes, data.length,
cryptData.mutableBytes, cryptData.length,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
base64cryptString = cryptData.base64EncodedString(options: .endLineWithLineFeed)
}
return base64cryptString
}
您可以通过传递需要加密的数据以及 NSData 格式的密钥和值来调用func testCrypt(data:NSData, keyData:NSData, ivData:NSData)
。
例如:
let data: NSData! = message.data(using: .utf8) as NSData!;
let keyData: NSData! = keyValue.data(using: .utf8) as NSData!;
let ivData: NSData! = ivValue.data(using: .utf8) as NSData!;
var base64cryptString = self.testCrypt(data: data, keyData: keyData, ivData: ivData)