How to decrypt a string in C # was encrypted in iOS using Rijndael

I am trying to encrypt and decrypt a string using object c and c #. both work fine in native code, but when I tried to decrypt the string in C # it was encrypted in iOS. I am getting some error.

This was the code I used in object c

- (NSData *)AES256EncryptWithKey:(NSString *)key  Data: (NSData *) data
{
    char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)

    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [data length];

    NSData *iv =  [@"abcdefghijklmnopqrstuvwxyz123456" dataUsingEncoding:NSUTF8StringEncoding];

    size_t bufferSize = dataLength + kCCBlockSizeAES128;

    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;

    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          [iv bytes] /* initialization vector (optional) */,
                                          [data bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesEncrypted);

    if (cryptStatus == kCCSuccess)
    {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }

    free(buffer); //free the buffer;

    return nil;
}

      

To find out how to decrypt in C # I give blockize 256, ivsize to 32 and use "RijndaelManaged ()". I am not using salt and password. Error: Something like "Cancellation is invalid and cannot be removed." I tried to install the add-on as well as PKCS7, but no, but nothing helps to decrypt.

can anyone help?

Edit: My C # code is here

public string DecryptString(string encrypted)
{
    string result = null;
    _encoder = new UTF8Encoding();
    if (!string.IsNullOrWhiteSpace(encrypted) && (encrypted.Length >= 32))
    {
        var messageBytes = Convert.FromBase64String(encrypted);
        using (var rm = new RijndaelManaged())
        { 
            rm.BlockSize = _blockSize;
            rm.Key = _encoder.GetBytes("mykey_here");
            rm.IV = _encoder.GetBytes("abcdefghijklmnopqrstuvwxyz123456"); ;
            rm.Padding = PaddingMode.Zeros;
            var decryptor = rm.CreateDecryptor(rm.Key, messageBytes.Take(_ivSize).ToArray());
            result = _encoder.GetString(Transform(messageBytes.Skip(_ivSize).ToArray(), decryptor));
        }
    }

    return result;
}

protected byte[] Transform(byte[] buffer, ICryptoTransform transform)
{
    byte[] result;
    using (var stream = new MemoryStream())
    using (var cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
    {
        cs.Write(buffer, 0, buffer.Length);
        cs.FlushFinalBlock();
        result = stream.ToArray();
    }

    return result;
}

      

+3


source to share


1 answer


iOS (Common Crypto) explicitly sets all encryption options, C # code implicitly sets many options. These implicit parameters, while simplifying use, are problematic when trying to achieve interoperability.

The C # class RijndaelManaged

allows you to explicitly specify a parameter, modify your code to use, specifically BlockSize

( 128

), KeySize

( 128

), Mode

( CipherMode.CBC

) and Padding

( PaddingMode.PKCS7

). The default values ​​for Mode

and Padding

are ok. See RijndaelManaged Documentation

AES and Rijndael are not the same, in particular, AES only uses a block size of 128 bits (16 bytes), while Rijndael allows multiple block sizes. Therefore, you need to specify a block size of 128 bits for Rijndael. So iv is also 128 bits (16 bytes). Both encryption keys support 128, 192 and 256 bytes.

You are probably better off using a class AESManaged

than a class RijndaelManaged

. See AesManaged Documentation

The C # side expects the data to be Base64 encoded, the iOS side will not show this encoding operation, make sure it is done on the iOS side.



Since you are using iv, make sure to use CBC mode on both sides. Common Crypto CBC mode uses default, make sure CBC mode is used on C # side.

Make sure the C # side is using PKCS # 7 or PKCS # 5 padding, they are equivalent. It looks like PKCS # 7 is the default on the C # side, so it should be OK.

It is best to use a well-sized key and not rely on default padding. In Common Crypto, the key size is explicitly specified and is filled with zero if the incoming key must be short. C # looks like it determines the key size from the provided key, in this case the key is 10 bytes, so the decryption key appears to be 128 bits by default and the key is internally filled with zeros. On iOS, you explicitly specify a key size of 256 bits. This is a misnomer and must be removed. Supply a key that is the exact size as given on the iOS side.

Finally, there is iv, C # code expects iv to be appended to encrypted data, but iOS code does not provide this. The solution is to change the iOS code to add iv to the encrypted code. Change iv to 16 bytes, AES block size.

Finally, give the hex dumps of the test data, data, iv and key just before and after the encryption call if you need more help.

+4


source







All Articles