.NET中的CryptoStream不会解密来自Objective-C的加密文件

时间:2013-09-03 10:40:46

标签: .net objective-c encryption cryptography aes

我正在.NET and Objective-C apps之间实现兼容的二进制文件加密/解密。我在RNCryptor方面使用Objective-C包。据我所知,我能够encrypt/decrypt字符串,但文件加密让我感到不安。问题是,当我读取文件并加密其数据并将其写入文件时,它不会在.NET app中解密。如果我计算Base64字符串的加密数据并在.NET中解密 - 从Base64字符串创建字节数组并使用与文件相同的登录解密,它会解密。 在Objective C and .NET CryptoStream ?

中将加密数据写入文件有什么区别吗

或者我错过了一些基本的东西? 目标C中加密文件的代码是: -

  RNEncryptor *encryptor = [[RNEncryptor alloc] initWithSettings:kRNCryptorAES256Settings
                                                          password:password
                                                           handler:^(RNCryptor *cryptor, NSData *data) {
                                                               @autoreleasepool
                                                               {
                                                                   NSLog(@"6length of out data %d",[data length]);

                                                                   [encodedText appendString:[data base64EncodingWithLineLength:0]];
                                                                   [outputStream write:data.bytes maxLength:data.length];

                                                                   dispatch_semaphore_signal(semaphore);

                                                                   data = nil;
                                                                   if (cryptor.isFinished)
                                                                   {

                                                                       [outputStream close];
                                                                       NSLog(@"my encryptedText  %@",encodedText);
                                                                       encryptionError = cryptor.error;
                                                                       // call my delegate that I'm finished with decrypting
                                                                   }
                                                               }
                                                           }];
    encryptor.filesize=[attrs fileSize];
    while (inputStream.hasBytesAvailable)
    {
        @autoreleasepool
        {
            uint8_t buf[blockSize];
            NSUInteger bytesRead = [inputStream read:buf maxLength:blockSize];
            if (bytesRead > 0)
            {
                NSData *data = [NSData dataWithBytes:buf length:bytesRead];

            }
                total = total + bytesRead;
                [encryptor addData:data];

                dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            }
        }
    }

    [inputStream close];

    [encryptor finish];
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}

解密

[encodedText appendString:[data base64EncodingWithLineLength:0]];

始终有效,但文件无法解密。

2 个答案:

答案 0 :(得分:1)

<强>更新

RNEncryptor实际上是一个高级加密api,用于正确执行,而它具有特殊的密文格式,这是典型的结构。要使您的dotnet代码与adhoc格式相匹配,您必须使用RNCryptor keyForPassword:salt:settings:RNCryptorKeyDerivationSettings匹配您的Rfc2898DeriveBytes。如:

   {
    .keySize = kCCKeySizeAES256,
    .saltSize = 16,
    .PBKDFAlgorithm = kCCPBKDF2,
    .PRF = kCCPRFHmacAlgSHA1,
    .rounds = 1000
   }

使用RNCryptorEngine进行加密,并布置与您的adhoc .net格式匹配的密文。

| IV (16 bytes) | Password Salt (16 bytes) | Ciphertext |

这假设明文的格式也是正确的

| message length (8 bytes) | const tag of some sort (8 bytes) | message | sha256 hash of message (32 bytes) |

如果你需要制作纯文本格式(我猜你也是这样),你可能只想直接使用iOS的内置CCCryptor而不是RNCryptor。

咨询:

为了其他遇到此问题的人的利益,海报的.net密文构造存在安全问题,请勿使用。

上一个答案

RNCryptor会对加密进行身份验证。

它实际上应该与我的代码兼容: Modern Examples of Symmetric Authenticated Encryption of a string (C#)

然后解密,使用RNEncryptor生成的内容,使用:

var plainText = AESThanHmac.SimpleDecryptWithPassword(encryptedMessage, password, nonSecretPayloadLength: 2);

nonSecretPayloadLength为2,因此它会跳过RNEncryptor Header的版本/选项。

答案 1 :(得分:0)

Base64编码需要输入大小为3的倍数(它将每3个字节转换为4个字符)。如果不是,则添加填充('='符号),不会在流中处理。