简体   繁体   English

aes解密\\ 0字符ios

[英]aes decryption \0 character ios

i've a problem..when i decrypt the data that is returned from my php page, if the length of the string is less than 16, the char \\0 is append to string. 我有一个问题..当我解密从我的php页面返回的数据时,如果字符串的长度小于16,则将char \\ 0追加到字符串之后。 Original string is: 100000065912248 I decrypt the encrypted string with this function: 原始字符串是: 100000065912248我使用此函数解密加密的字符串:

#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;
}

I send a nil "iv" parameter to the function and after i use "cIv" in function, and it contain this: 我向函数发送一个nil“ iv”参数,然后在函数中使用“ cIv”,它包含以下内容: 简历说明

The result is exactly, but the length of string is 16 instead of 15 (string: 100000065912248). 结果是准确的,但是字符串的长度是16而不是15(字符串:100000065912248)。 In fact, the last character is \\0. 实际上,最后一个字符是\\ 0。

Why? 为什么? how can i solve? 我该如何解决?

EDIT: 编辑:

PHP encrypt function: PHP加密功能:

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 is a block cypher and encrypts/decrypts blocks of length 128 bits (16 bytes). AES是一个块密码,用于加密/解密长度为128位(16字节)的块。 So if the data is not a block size some padding must be added. 因此,如果数据不是块大小,则必须添加一些填充。 The most popular and supported by Apple is PKCS7. 苹果公司最受欢迎和支持的是PKCS7。

Interfacing with PHP one must consider padding and possible base64 encoding. 与PHP的接口必须考虑填充和可能的base64编码。

The solution is to use the same padding on both sides, PHP and iOS. 解决方案是在PHP和iOS双方上使用相同的填充。

AES always operates on 16 bytes, there is no option--so, if you have 15 bytes a byte is going to have to be added, that is padding. AES始终在16个字节上运行,没有选项-因此,如果您有15个字节,则必须添加一个字节,即填充。 From what I understand (not much about PHP encryption) PHP does not do true PCKS7padding and it is best to pad yourself. 据我了解(对PHP加密了解不多),PHP并不是真正的PCKS7padding,最好是自己动手做。 Lookup PKCS7 in Wikipedia. 在Wikipedia中查找PKCS7。

You should be OK with zero padding (the default) if you only operate on strings, but I would recommend PKCS#7 padding, if only for interoperability reasons. 如果仅对字符串进行操作,则应该使用零填充(默认),但是如果出于互操作性原因,我建议使用PKCS#7填充。

With zero padding the plaintext is padded with 00 valued bytes, but only if required. 使用零填充时,纯文本将填充00值的字节,但仅在需要时才填充。 This is different from PKCS#7 padding, which is always deployed. 这与始终部署的PKCS#7填充不同。 After decryption you can use the trim function on the resulting plaintext after decryption. 解密后,可以对解密后的纯文本使用trim功能。 You should then get the original string. 然后,您应该获得原始字符串。

This obviously wont work on binary data because it may end with a character that is removed by the trim function. 这显然不适用于二进制数据,因为它的结尾可能是trim函数删除的字符。 Beware that trim in PHP seems to strip off 00 bytes. 请注意,PHP中的trim似乎剥夺了00个字节。 This is not a given, officially 00 is not whitespace, even though it is treated that way by many runtimes. 这不是给定的,尽管许多运行时都以这种方式对待,但正式地00不是空格。

You have to remove padding from the decrypted data 您必须从解密的数据中删除填充

function removePadding($decryptedText){
    $strPad = ord($decryptedText[strlen($decryptedText)-1]);
    $decryptedText= substr($decryptedText, 0, -$strPad);
    return $decryptedText;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM