gpt4 book ai didi

ios - CCCrypt 上的 EXC_BAD_ACCESS 代码 2

转载 作者:可可西里 更新时间:2023-11-01 06:06:07 24 4
gpt4 key购买 nike

我正在尝试使用 DES 加密来加密密码(不要问为什么 DES,我知道它不太安全)。我是第一次在 iOS 中这样做,因此不得不依赖另一篇关于如何做的帖子。

当我运行加密时它返回空值,与解密一个已经加密的字符串相同(我使用在线工具加密)。当我设置断点以查看发生了什么时,它在 CCCrypt 处停止,并提到 EXC_BAD_ACCESS (Code 2)

我尝试使用不同的 CCOptions,但它总是返回相同的内容。任何提示出了什么问题?是否需要 iv 字符串?

我使用了以下 NSString 类别来加密或解密字符串 -

#import "NSString+DES.h"

@implementation NSString(DES)

- (NSString*) encryptDES: (NSString *) key
{
const void *vplainText;
size_t plainTextBufferSize;

plainTextBufferSize = [self length];
vplainText = (const void *) [self UTF8String];

CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t *movedBytes;

bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
// memset((void *) iv, 0x0, (size_t) sizeof(iv));


//NSString *initVec = @"init Vec";
const void *vkey = (const void *) [key UTF8String];
//const void *vinitVec = (const void *) [initVec UTF8String];

ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
vkey,
kCCKeySizeDES,
NULL,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
movedBytes);

NSString *result;
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [myData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
return result;
}

- (NSString *) decryptDES: (NSString *) key
{
const void *vplainText;
size_t plainTextBufferSize;

plainTextBufferSize = [self length];
vplainText = (const void *) [self UTF8String];

CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t *movedBytes;

bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
// memset((void *) iv, 0x0, (size_t) sizeof(iv));


//NSString *initVec = @"init Vec";
const void *vkey = (const void *) [key UTF8String];
//const void *vinitVec = (const void *) [initVec UTF8String];

ccStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
vkey, //"123456789012345678901234", //key
kCCKeySizeDES,
NULL,// vinitVec, //"init Vec", //iv,
vplainText, //"Your Name", //plainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
movedBytes);

NSString *result;
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [myData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
return result;
}

@end

更新:

我又检查了几个地方并稍微更改了代码,加密有效但没有用正确的值解密。

例如,当我使用 YourName 作为字符串和 12345 作为 key 时,我得到 Fu2sK61e7l5rkXRhAKjPWA== 作为加密代码,但是解密返回 +54qWCYTB5LkdARDZjAow== 而不是 YourName

更新代码:

#import "NSString+DES.h"

@implementation NSString(DES)

- (NSString*) encryptDES: (NSString *) key
{
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSData *stringData = [self dataUsingEncoding:NSUTF8StringEncoding];
size_t numBytesEncrypted = 0;
size_t bufferSize = stringData.length + kCCBlockSizeDES;
void *buffer = malloc(bufferSize);

CCCryptorStatus result = CCCrypt( kCCEncrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding,
keyData.bytes, kCCKeySizeDES,
NULL,
stringData.bytes, stringData.length,
buffer, bufferSize,
&numBytesEncrypted);
NSData *output = [NSData dataWithBytes:buffer length:numBytesEncrypted];
free(buffer);
if( result == kCCSuccess )
{
NSString *resultStr = [output base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
return resultStr;
} else {
NSLog(@"Failed DES encrypt...");
return nil;
}

}

- (NSString *) decryptDES: (NSString *) key
{
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSData *stringData = [[NSData alloc] initWithBase64EncodedString:self options:0];

size_t numBytesEncrypted = 0;
size_t bufferSize = stringData.length + kCCBlockSizeDES;
void *buffer = malloc(bufferSize);

CCCryptorStatus result = CCCrypt( kCCDecrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding,
keyData.bytes, kCCKeySizeDES,
NULL,
stringData.bytes, stringData.length,
buffer, bufferSize,
&numBytesEncrypted);
NSData *output = [NSData dataWithBytes:buffer length:numBytesEncrypted];
free(buffer);
if( result == kCCSuccess )
{
NSString *resultStr = [output base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
return resultStr;
} else {
NSLog(@"Failed DES decrypt...");
return nil;
}
}

@end

最佳答案

似乎普遍混淆了算法,DES 或 3DES,混合使用但 key 是 3DES(24 字节)。 key 需要更改为 8 字节。 block 大小常量也应更改为 kCCBlockSizeDES,但这不会导致错误,因为它是相同的值。

对于方法:

- (NSString *) decryptDES: (NSString *) key

坏访问错误是因为没有为movedBytes分配存储,只是一个指针。将声明更改为:

size_t movedBytes;

CCCrypt 中对 movedBytes 的引用更改为 &movedBytes

加密测试输出:

string: "Your Name"
key: "12345678"

movedBytes: 16
myData: 136142f6 6cd98e01 af1eef46 28d36499
result: E2FC9mzZjgGvHu9GKNNkmQ==

请求注释:

ECB 模式不使用 iv。

对于DES, key 需要恰好是8个字节,如果太短,结果将是不确定的。在更新后的代码中, key 为 5 字节,但长度为 8 字节 (kCCKeySizeDES),因此丢失的三个 key 字节将是 keyData 之后的任何字节。

更新的答案没有指定ECB模式,默认是CBC模式。添加 kCCOptionECBMode

在解密时不要使用Base64编码,将数据转换为NSString:

NSString * resultStr = [[NSString alloc] initWithData:output encoding:NSUTF8StringEncoding];  

如果使用使用 php mcrypt 函数的在线加密,数据的最后一个 block 将不正确,因为 mcrypt 不支持 PKCS#7 填充,它使用非标准和不安全的空填充。

关于ios - CCCrypt 上的 EXC_BAD_ACCESS 代码 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29984798/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com