-1

我正在使用 CommonCrypto CCCryptorCreate 来解密消息。我正在使用密码和 IV,但它总是返回 nil。

如果我使用 CCCryptorCreate 进行解密,但在 RUBY 端加密期间不使用 IV 并且不在 obj-c 解密端使用 IV,则解密工作完美,我可以看到消息。

但是,如果我在 RUBY 上使用 IV 并在 obj-c 端使用 IV,则解密以 nil 消息对象结束。

在Objective-C中使用这个加密/在Ruby中使用任何东西解密

OBJ-C方法:

    - (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
                                         key: (id) key      // data or string
                        initializationVector: (id) iv       // data or string
                                     options: (CCOptions) options
                                       error: (CCCryptorStatus *) error
    {
        CCCryptorRef cryptor = NULL;
        CCCryptorStatus status = kCCSuccess;

        NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
        NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]);

        NSMutableData * keyData, * ivData;
        if ( [key isKindOfClass: [NSData class]] )
            keyData = (NSMutableData *) [key mutableCopy];
        else
            keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];

        if ( [iv isKindOfClass: [NSString class]] )
            ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
        else
            ivData = (NSMutableData *) [iv mutableCopy];    // data or nil

        #if !__has_feature(objc_arc)
            [keyData autorelease];
            [ivData autorelease];
        #endif

        // ensure correct lengths for key and iv data, based on algorithms
        FixKeyLengths( algorithm, keyData, ivData );

        status = CCCryptorCreate( kCCDecrypt, algorithm, options,
                               [keyData bytes], [keyData length], [ivData bytes],
                               &cryptor );

        if ( status != kCCSuccess )
        {
            if ( error != NULL )
                *error = status;
            return ( nil );
        }

        NSData * result = [self _runCryptor: cryptor result: &status];
        if ( (result == nil) && (error != NULL) )
            *error = status;

        CCCryptorRelease( cryptor );

        return ( result );
    }




=== DOES NOT WORK ====
NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmAES128
                                                key: [[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash]
                               initializationVector: [anIV dataUsingEncoding:NSUTF8StringEncoding]
                                            options: kCCOptionPKCS7Padding
                                              error: &status];


=== DOES WORK ===
NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmAES128
                                                key: [[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash]
                               initializationVector: nil
                                            options: kCCOptionPKCS7Padding
                                              error: &status];
4

1 回答 1

0

看起来 iv 可能不同,请确保数据字节相同且长度正确。

你想做CCCrypt一次性加密。

来自 Apple:CCCrypt是一种无状态的一次性加密或解密操作。这基本上执行了CCCrytorCreate(), CCCryptorUpdate(),CCCryptorFinal()和的序列CCCryptorRelease()

由于您没有使用CCCrypt,因此您至少必须添加CCCryptorFinal()到您的示例中。

另请注意,密钥和 iv 确实需要完全正确的字节大小。NSUTF8StringEncoding如果某些字符需要多字节编码,则使用可能不会产生预期的字节数。注意:“i”可以编码为代理对。

不要使用密码字符串而不使用PBKDF2生成好的密钥。

除非你真的知道你在用加密做什么,否则考虑使用RNCryptor 。

这是一次性加密/解密方法的简单示例
代码 key 和 iv 必须恰好是所需的长度。
任何编码(Base64、NSString 等)都在此方法之外完成。

+ (NSData *)doCipher:(NSData *)dataIn
                  iv:(NSData *)iv
                 key:(NSData *)symmetricKey
             context:(CCOperation)encryptOrDecrypt // kCCEncrypt or kCCDecrypt
               error:(NSError **)error
{
    CCCryptorStatus ccStatus   = kCCSuccess;
    size_t          cryptBytes = 0;
    NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];

    ccStatus = CCCrypt( encryptOrDecrypt,
                       kCCAlgorithmAES128,
                       kCCOptionPKCS7Padding,
                       symmetricKey.bytes, 
                       kCCKeySizeAES128,
                       iv.bytes,
                       dataIn.bytes,
                       dataIn.length,
                       dataOut.mutableBytes,
                       dataOut.length,
                       &cryptBytes);

    if (ccStatus == kCCSuccess) {
        dataOut.length = cryptBytes;
    }
    else {
        if (error) {
            *error = [NSError errorWithDomain:@"kEncryptionError"
                                         code:ccStatus
                                     userInfo:nil];
        }
        dataOut = nil;
    }

    return dataOut;
}
于 2014-06-27T20:01:13.127 回答