Stephane Van Rossem
Stephane Van Rossem

Reputation: 11

System.Security.Cryptography.Cng: The parameter is incorrect

I used standard code to get this file encrypted. The certificate is not expired and the key is valid. I don't find the reason why it throws this exception.


        public byte[] EncryptDataOaepSha256(X509Certificate2 cert, byte[] data)
        {
            RSA rsa = cert.GetRSAPublicKey();

            if (rsa != null)
            {
                return rsa.Encrypt(data, RSAEncryptionPadding.OaepSHA256);
            }

           return null;
        }

enter image description here

Upvotes: 0

Views: 1132

Answers (3)

Omid Moridi
Omid Moridi

Reputation: 41

In the previous post, there is a small error in the code, which has been fixed. Also, it has been changed from SHA256 to SHA512, which changes the block size. Therefore, the input is 382 bytes and the output is 512 bytes, which you should save. Now your block is 512 bytes which are lined up. To read from decrypt, well, you have to separate the 512-byte packet and check it.

for Encrypt

RSA? rsa = Certificate.GetRSAPublicKey();
byte[] input=data;
long blockSize = 382;
byte[] output = Array.Empty<byte>();
try {
    for (long i = 0; i < input.Length; i += blockSize)
    {
        long chunkSize = (input.Length - i > blockSize) ? blockSize : input.Length - i;
        byte[] temp = new byte[chunkSize];
        temp = temp.ToArray();
        Array.Copy(input, i, temp, 0, chunkSize);
        byte[] encryptedByte = rsa.Encrypt(temp, RSAEncryptionPadding.OaepSHA512);

        if (output.Length > 0)
            output = output.Concat(encryptedByte).ToArray();
        else
            output = encryptedByte;
    }
}
catch (Exception e)
{
    
}

for Decrypt

RSA? rsa = Certificate.GetRSAPrivateKey();
byte[] input=data;
long blockSize = 512;
byte[] output = Array.Empty<byte>();

try
{
    for (long i = 0; i < input.Length; i += blockSize)
    {
        long chunkSize = (input.Length - i > blockSize) ? blockSize : input.Length - i;
        byte[] temp = new byte[chunkSize];
        Array.Copy(input, i, temp, 0, chunkSize);

        byte[] encryptedByte = rsa.Decrypt(temp, RSAEncryptionPadding.OaepSHA512);

        if (output.Length > 0)
            output = output.Concat(encryptedByte).ToArray();
        else
            output = encryptedByte;
    }
}
catch (Exception e)
{}

use output for your reason.

Upvotes: 0

Stephane Van Rossem
Stephane Van Rossem

Reputation: 11

@jdweng thanks for the code i fixed the problem to do this

   public byte[] EncryptDataOaepSha256(X509Certificate2 cert, byte[] data, ILogger log)
    {
        RSA rsa = cert.GetRSAPublicKey();
        byte[] input = data;
        long blocksize = 182;
        long byteCounterInt = 0;
        byte[] byteCounter = BitConverter.GetBytes(byteCounterInt);
        byte[] output = new byte[0];

        try
        {
            for (long i = 0; i < input.Length; i += blocksize)
            {
                long chunksize = (input.Length - i > blocksize) ? blocksize : input.Length - i;
                byte[] temp = new byte[chunksize];
                temp = temp.Concat(byteCounter).ToArray();
                Array.Copy(input, i, temp, 0, chunksize);
                byte[] encrypteByte = rsa.Encrypt(temp, RSAEncryptionPadding.OaepSHA256);

                if (output.Length > 0)
                {
                    output = output.Concat(encrypteByte).ToArray();
                }
                else
                {
                    output = encrypteByte;
                }
            }

            return output;
        }
        catch(Exception e)
        {
            log.LogCritical("Error encrypting a stream");
            log.LogCritical(e.Message);
            log.LogCritical(e.StackTrace);
            log.LogCritical(e.ToString());

            return null;
        }
    }

 public byte[] DecryptDataOaepSha256(X509Certificate2 cert, byte[] data, ILogger log)
    {
        RSA rsa = cert.GetRSAPublicKey();

        byte[] input = data;
        long blocksize = 190;
        long byteCounterInt = 0;
        byte[] byteCounter = BitConverter.GetBytes(byteCounterInt);
        byte[] output = new byte[0];

        try
        {
            for (long i = 0; i < input.Length; i += blocksize)
            {
                long chunksize = (input.Length - i > blocksize) ? blocksize : input.Length - i;
                byte[] temp = new byte[chunksize];
                Array.Copy(input, i, temp, 0, chunksize);
                byte[] tempMinBytecount = new byte[temp.Length - byteCounter.Length];
                Array.Copy(temp, byteCounter.Length, tempMinBytecount, 0, tempMinBytecount.Length);

                byte[] decrypteByte = rsa.Decrypt(tempMinBytecount, RSAEncryptionPadding.OaepSHA256);

                if (output.Length > 0)
                {
                    output = output.Concat(decrypteByte).ToArray();
                }
                else
                {
                    output = decrypteByte;
                }
            }

            return output;
        }
        catch (Exception e)
        {
            log.LogCritical("Error decrypting a stream");
            log.LogCritical(e.Message);
            log.LogCritical(e.StackTrace);
            log.LogCritical(e.ToString());

            return null;
        }

    }

Upvotes: 0

jdweng
jdweng

Reputation: 34421

Try code like below to break array into smaller pieces

            byte[] input = null;
            long blocksize = 1000000;
            for(long i = 0; i < input.Length; i += blocksize)
            {
                long chunksize = (input.Length - i > blocksize) ? blocksize : input.Length - i;
                byte[] temp = new byte[chunksize];
                Array.Copy(input, i, temp, 0, chunksize);
            }

Upvotes: 0

Related Questions