0

I'm encrypting a big string with TDES and trying to decrypt it. Can't understand what's is wrong. When it does the READ function in decryption I get "Bad Data" from the Cryptographic Exception. (I marked the line with comments)

To generate and encrypt the string:

public void MssGenerateKeyPair(string ssSymmetricKey, out string ssCipheredKeyPair, out string ssPublicKey) {
        ssCipheredKeyPair = string.Empty;
        ssPublicKey = string.Empty;

        //Symmetric key is the hash of user's signing password
        SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
        byte[] tempKey = sha1.ComputeHash(Encoding.UTF8.GetBytes(ssSymmetricKey));
        byte[] key = new byte[24];
        tempKey.CopyTo(key, 0);
        //if symmetric keys is < 24
        for (int index = 0, i = tempKey.Length; i < key.Length; index++, i++)
        {
            key[i] = tempKey[index];
        }

        //define symmetric encryption data
        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        tdes.Key = key;
        tdes.IV = new byte[8];
        tdes.Mode = CipherMode.CBC;
        tdes.Padding = PaddingMode.PKCS7;

        //define assymetric stuff
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, tdes.CreateEncryptor(), CryptoStreamMode.Write);
        byte[] toChipher = Encoding.UTF8.GetBytes(rsa.ToXmlString(true));
        cryptoStream.Write(toChipher, 0, toChipher.Length);
        byte[] cipheredKeyPair = memoryStream.ToArray();
        ssCipheredKeyPair = Convert.ToBase64String(cipheredKeyPair);
        ssPublicKey = rsa.ToXmlString(false);
        cryptoStream.Close();
        memoryStream.Close();


    } // MssGenerateKeyPair

To decrypt the string

public void MssSignData(string ssSymmetricKey, byte[] ssDataToSign, byte[] ssCipheredKeyPair, out byte[] ssSignature, out byte[] ssSignedData) {
        ssSignature = new byte[] {};
        ssSignedData = new byte[] {};

        //Symmetric key is the hash of user's signing password
        SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
        byte[] tempKey = sha1.ComputeHash(Encoding.UTF8.GetBytes(ssSymmetricKey));
        byte[] key = new byte[24];
        tempKey.CopyTo(key, 0);
        //if symmetric keys is < 24
        for (int index = 0, i = tempKey.Length; i < key.Length; index++, i++)
        {
            key[i] = tempKey[index];
        }

        //define symmetric encryption data
        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        tdes.Key = key;
        tdes.IV = new byte[8];
        tdes.Mode = CipherMode.CBC;
        tdes.Padding = PaddingMode.PKCS7;

        MemoryStream memoryStream = new MemoryStream(ssCipheredKeyPair);
        CryptoStream cryptoStream = new CryptoStream(memoryStream, tdes.CreateDecryptor(), CryptoStreamMode.Read);
        MemoryStream plainMemoryStream = new MemoryStream();

        byte[] tempPlainBytes = new byte[1024];

        int read = 0;
        int totalRead = 0;
        do
        {
            //################################################################
            //ERROR IN THE FOLLOWING LINE
            //################################################################
            read = cryptoStream.Read(tempPlainBytes, 0, tempPlainBytes.Length);
            totalRead += read;
            plainMemoryStream.Write(tempPlainBytes, 0, read);
        } while (read > 0);

        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        rsa.FromXmlString(Encoding.UTF8.GetString(plainMemoryStream.ToArray()));

        ssSignature = rsa.SignData(ssDataToSign, new SHA1CryptoServiceProvider());
        ssSignedData = ssDataToSign;
        cryptoStream.Close();
        memoryStream.Close();
        plainMemoryStream.Close();

    } // MssSignData

Code to test

 private void button1_Click(object sender, EventArgs e)
    {
        string key;
        string pkey;
        byte[] sig;
        byte[] avs;

        OutSystems.NssPseudoCertificates.CssPseudoCertificates c = new OutSystems.NssPseudoCertificates.CssPseudoCertificates();

        c.MssGenerateKeyPair("xpto",out key, out pkey);
        c.MssSignString("xpto", "hello", key, out sig, out avs);


    }
Miguel Ribeiro
  • 8,057
  • 20
  • 51
  • 74
  • 1
    Tip: You should use the `using` statement to handle the closing of streams (and other IDisposable resources) in case exceptions are thrown. It's probably not your problem, but it may help you avoid other problems later on. (http://msdn.microsoft.com/en-us/library/yh598w02(v=VS.100).aspx) – R. Martinho Fernandes Dec 22 '10 at 18:30
  • 2
    You might want to add a "Flush" to your memorystream or a "FlushFinalBlock" on your encryptoStream. TDES is just doing DES 3 times, and since DES is a block cypher, we need to make sure it's "block size padded". – Marvin Smit Dec 22 '10 at 19:12
  • @Marvin Smit: It is padding by using the PKCS7 padding scheme, and close() should flush the stream. – President James K. Polk Dec 22 '10 at 23:31
  • @GregS: you're saying I shouldn't use PKCS7? Should ue what? Zeros? – Miguel Ribeiro Dec 23 '10 at 00:40

1 Answers1

0

Like Marvin Smit said in his comments: to add the flush, I did it and worked! Credits go to him!

Miguel Ribeiro
  • 8,057
  • 20
  • 51
  • 74