AES 128加密提供了特殊的功能

时间:2016-09-12 10:09:52

标签: php ios objective-c encryption cryptography

我正在尝试使用密钥和iv进行AES128加密,然后转换为十六进制字符串。我的问题是,当我将字符串加密到aes128并转换为十六进制时,它会给我一个十六进制字符串。但是当我尝试同样的事情时php我得到不同的十六进制字符串。所以当我尝试解密php十六进制字符串时,它的解密成功。但是当我尝试在php中解密我的十六进制字符串时,它会给我一些特殊字符。

 NSString *str  = @"hello";
 NSString *key = @"1234abcd5678abcd1234abcd5678abcd";
 NSString *IV = @"1234567812345678";

NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSData* responseData  = [data AES128EncryptedDataWithKey:key iv:IV];
NSLog(@"%@",[self hexRepresentationWithSpaces_AS:NO withdata:responseData]);


- (NSData *)AES128Operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv
{
    char keyPtr[kCCKeySizeAES128 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    char ivPtr[kCCBlockSizeAES128 + 1];
    bzero(ivPtr, sizeof(ivPtr));
    if (iv) {
        [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    }

    NSUInteger dataLength = [self length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(operation,
                                          kCCAlgorithmAES,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          ivPtr,
                                          [self bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    free(buffer);
    return nil;
}

-(NSString*)hexRepresentationWithSpaces_AS:(BOOL)spaces withdata:(NSData*)data
{
    const unsigned char* bytes = (const unsigned char*)[data bytes];
    NSUInteger nbBytes = [data length];
    //If spaces is true, insert a space every this many input bytes (twice this many output characters).
    static const NSUInteger spaceEveryThisManyBytes = 4UL;
    //If spaces is true, insert a line-break instead of a space every this many spaces.
    static const NSUInteger lineBreakEveryThisManySpaces = 4UL;
    const NSUInteger lineBreakEveryThisManyBytes = spaceEveryThisManyBytes * lineBreakEveryThisManySpaces;
    NSUInteger strLen = 2*nbBytes + (spaces ? nbBytes/spaceEveryThisManyBytes : 0);

    NSMutableString* hex = [[NSMutableString alloc] initWithCapacity:strLen];
    for(NSUInteger i=0; i<nbBytes; ) {
        [hex appendFormat:@"%02X", bytes[i]];
        //We need to increment here so that the every-n-bytes computations are right.
        ++i;

        if (spaces) {
            if (i % lineBreakEveryThisManyBytes == 0) [hex appendString:@"\n"];
            else if (i % spaceEveryThisManyBytes == 0) [hex appendString:@" "];
        }
    }

    return hex ;
}

和在php我正在使用

$td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv);
mcrypt_generic_init($td, $key, $iv);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
// mcrypt_module_close($td);


echo $hexdata = bin2hex($encrypted);
echo "<br>";

 $bindata = '';

for ($i = 0; $i < strlen($hexdata); $i += 2) {
   $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
}


echo $bindata;
echo "<br>";

mcrypt_generic_init($td, $key, $iv);
$decrypted = mdecrypt_generic($td,$encrypted);
mcrypt_generic_deinit($td);
echo "encrypted : ".$encrypted;
echo "<br>";
echo "decrypted : ".$decrypted;

1 个答案:

答案 0 :(得分:1)

mcrypt是一个非常古老的库,甚至没有实现PKCS#7兼容的填充,你显然在你的iOS代码中使用它。所以最后你会得到一个填充的字符表示,它可能会替换为替换字符。

错误的IV将导致16个字符错误,所有字符错误的错误键。您可能还希望匹配UTF-8编码,以便能够显示代码点高于0x7F的字符。