Decrypting bytes that were encrypted using RNCryptor

389 Views Asked by At

There's a third party application that's encrypting files with AES256 using RNCryptor, and I'm trying to decrypt those files in my C# application. All I was given is the key size (256) and the password string.

Here is how the files are being encrypted before being sent to me:

    NSData *data = [@"Data" dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSData *encryptedData = [RNEncryptor encryptData:data
                                      withSettings:kRNCryptorAES256Settings
                                      password:aPassword
                                         error:&error];

I'm still learning how to encrypt/decrypt, so I'm not exactly sure how to approach this. All the decryption examples I've seen here seem to require an IV and salt (and sometimes even password iterations), but as you can see from the code above, there's no mention of any of these things when the files are being encrypted.

Here is what I've got so far:

    public static string DecryptString(byte[] encryptedString, byte[] encryptionKey)
    {
        using (var provider = new AesCryptoServiceProvider())
        {
            provider.Key = encryptionKey;
            provider.Mode = CipherMode.CBC;
            provider.Padding = PaddingMode.PKCS7;
            using (var ms = new MemoryStream(encryptedString))
            {
                byte[] buffer = null;
                ms.Read(buffer, 0, 16);
                provider.IV = buffer;
                using (var decryptor = provider.CreateDecryptor(provider.Key, provider.IV))
                {
                    using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                    {
                        byte[] decrypted = new byte[encryptedString.Length];
                        var byteCount = cs.Read(decrypted, 0, encryptedString.Length);
                        return Encoding.UTF8.GetString(decrypted, 0, byteCount);
                    }
                }
            }
        }

So I found that I can get the IV from the first 16 bytes, but that still leaves the problem of the encryption key which I can't convert to bytes without a salt value.

I feel lost. What do I do here?

2

There are 2 best solutions below

0
user928112 On

RNCryptor's documentation has the information I need right here: https://github.com/RNCryptor/RNCryptor-Spec/blob/master/RNCryptor-Spec-v3.md

Byte:     |    0    |    1    |      2-9       |  10-17   | 18-33 | <-      ...     -> | n-32 - n |
Contents: | version | options | encryptionSalt | HMACSalt |  IV   | ... ciphertext ... |   HMAC   |
  • version (1 byte): Data format version. Currently 3.
  • options (1 byte): bit 0 - uses password
  • encryptionSalt (8 bytes): iff option includes "uses password"
  • HMACSalt (8 bytes): iff options includes "uses password"
  • IV (16 bytes)
  • ciphertext (variable) -- Encrypted in CBC mode
  • HMAC (32 bytes)
0
Rob Napier On

The RNCryptor format has been implemented in various languages. The C# one is https://github.com/RNCryptor/RNCryptor-cs.

Note that the C# implementation is not a particularly strong one because of how it deals with bytes vs strings. PRs are welcome. While I don’t generally support the C# implementation, if it is critical to you, reach out and I’d be happy to discuss a short term contract.