aes解密\0个字符的ios
我有个问题..当我解密从php页面返回的数据时, 如果字符串的长度小于16,则字符\0将附加到字符串。 原始字符串为:100000065912248 我使用此函数解密加密字符串:aes解密\0个字符的ios,ios,encryption,aes,Ios,Encryption,Aes,我有个问题..当我解密从php页面返回的数据时, 如果字符串的长度小于16,则字符\0将附加到字符串。 原始字符串为:100000065912248 我使用此函数解密加密字符串: #define FBENCRYPT_ALGORITHM kCCAlgorithmAES128 #define FBENCRYPT_BLOCK_SIZE kCCBlockSizeAES128 #define FBENCRYPT_KEY_SIZE kCCKeySizeAES256 + (NSDat
#define FBENCRYPT_ALGORITHM kCCAlgorithmAES128
#define FBENCRYPT_BLOCK_SIZE kCCBlockSizeAES128
#define FBENCRYPT_KEY_SIZE kCCKeySizeAES256
+ (NSData*)decryptData:(NSData*)data key:(NSData*)key iv:(NSData*)iv;
{
NSData* result = nil;
// setup key
unsigned char cKey[FBENCRYPT_KEY_SIZE];
bzero(cKey, sizeof(cKey));
[key getBytes:cKey length:FBENCRYPT_KEY_SIZE];
// setup iv
char cIv[FBENCRYPT_BLOCK_SIZE];
bzero(cIv, FBENCRYPT_BLOCK_SIZE);
if (iv) {
[iv getBytes:cIv length:FBENCRYPT_BLOCK_SIZE];
}
// setup output buffer
size_t bufferSize = [data length] + FBENCRYPT_BLOCK_SIZE;
void *buffer = malloc(bufferSize);
int length = [data length];
// do decrypt
size_t decryptedSize = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
FBENCRYPT_ALGORITHM,
0,
cKey,
FBENCRYPT_KEY_SIZE,
cIv,
[data bytes],
[data length],
buffer,
bufferSize,
&decryptedSize);
if (cryptStatus == kCCSuccess) {
result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
} else {
free(buffer);
NSLog(@"[ERROR] failed to decrypt| CCCryptoStatus: %d", cryptStatus);
}
return result;
}
function encrypt($plaintext) {
$key = 'a16byteslongkey!a16byteslongkey!';
$base64encoded_ciphertext = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC));
$base64encoded_ciphertext = trim($base64encoded_ciphertext);
return $base64encoded_ciphertext;
}
我向函数发送一个nil“iv”参数,在函数中使用“cIv”之后,它包含以下内容:
结果正好是,但字符串的长度是16而不是15(字符串:100000065912248)。实际上,最后一个字符是\0
为什么??我怎样才能解决这个问题
编辑:
PHP加密函数:
#define FBENCRYPT_ALGORITHM kCCAlgorithmAES128
#define FBENCRYPT_BLOCK_SIZE kCCBlockSizeAES128
#define FBENCRYPT_KEY_SIZE kCCKeySizeAES256
+ (NSData*)decryptData:(NSData*)data key:(NSData*)key iv:(NSData*)iv;
{
NSData* result = nil;
// setup key
unsigned char cKey[FBENCRYPT_KEY_SIZE];
bzero(cKey, sizeof(cKey));
[key getBytes:cKey length:FBENCRYPT_KEY_SIZE];
// setup iv
char cIv[FBENCRYPT_BLOCK_SIZE];
bzero(cIv, FBENCRYPT_BLOCK_SIZE);
if (iv) {
[iv getBytes:cIv length:FBENCRYPT_BLOCK_SIZE];
}
// setup output buffer
size_t bufferSize = [data length] + FBENCRYPT_BLOCK_SIZE;
void *buffer = malloc(bufferSize);
int length = [data length];
// do decrypt
size_t decryptedSize = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
FBENCRYPT_ALGORITHM,
0,
cKey,
FBENCRYPT_KEY_SIZE,
cIv,
[data bytes],
[data length],
buffer,
bufferSize,
&decryptedSize);
if (cryptStatus == kCCSuccess) {
result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
} else {
free(buffer);
NSLog(@"[ERROR] failed to decrypt| CCCryptoStatus: %d", cryptStatus);
}
return result;
}
function encrypt($plaintext) {
$key = 'a16byteslongkey!a16byteslongkey!';
$base64encoded_ciphertext = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC));
$base64encoded_ciphertext = trim($base64encoded_ciphertext);
return $base64encoded_ciphertext;
}
AES是块密码,加密/解密长度为128位(16字节)的块。因此,如果数据不是块大小,则必须添加一些填充。最受欢迎和苹果支持的是PKCS7
与PHP接口必须考虑填充和可能的Base64编码。
解决方案是在PHP和iOS两侧使用相同的填充AES总是在16个字节上运行,没有选项——所以,如果您有15个字节,那么必须添加一个字节,这就是填充。据我所知(对PHP加密了解不多),PHP并没有真正的PCKS7填充,最好自己填充。在Wikipedia中查找PKCS7。如果您只对字符串进行操作,则可以使用零填充(默认设置),但我建议使用PKCS#7填充,如果只是出于互操作性的原因 零填充时,纯文本用
00
值字节填充,但仅在需要时。这与总是部署的PKCS#7填充不同。解密后,您可以对解密后生成的明文使用trim
函数。然后您应该获得原始字符串
这显然不适用于二进制数据,因为它可能以被
trim
函数删除的字符结尾。请注意,PHP中的trim
似乎会剥离00
字节。这不是给定的,官方的00
不是空白,即使许多运行时都是这样处理的。您必须从解密的数据中删除填充
function removePadding($decryptedText){
$strPad = ord($decryptedText[strlen($decryptedText)-1]);
$decryptedText= substr($decryptedText, 0, -$strPad);
return $decryptedText;
}
但是我的php函数不使用填充(我用php函数编辑了文章),ECB/CBC模式下的AES通常使用填充。流模式不需要填充,ECB/CBC可能部署密文窃取。AES作为一种分组密码确实总是在16字节上运行,但您仍然可以选择一种不需要填充的模式。@owlstead虽然流模式在某些情况下很好,看起来很吸引人,但它们很难正确:从不使用相同的nonce等。因此我个人不推荐它们。我不是在批评答案(我投了赞成票)但我只是想指出,填充的需要取决于分组密码模式,而不是密码本身。@owlstead我同意你的观点。一般来说,密文上的
trim
on ciphertext`不是一个好主意。答案代码将不适用于PHP mcrypt默认的空填充,而这正是OP使用的。对于PKCS#7/PKCS#5填充,需要检查填充是否有效。考虑使用错误的键,<代码> $StPad < /Cord>很可能是错误的,可能是一个大于数据长度的值。但不要返回一个错误的填充错误,它倾向于创建一个填充oracle,而只是什么也不做。大多数库都支持PKCS#7填充,并将在加密时自动添加填充,在解密时删除填充–无需执行更多操作。