Archive for the ‘Encryption’ Category

Question:
We’re trying to sync up our Chilkat component with another encryption component but can’t get the initialization vector to match. Is that compiled into the Chilkat module, or can it be changed via a component property?

Answer:
Yes, the Chilkat encryption component provides the “IV” property. The type depends on the programming language:

ActiveX:  Variant containing byte array.
.NET (C#, VB.NET): byte array
C++: CkByteData object (containing the bytes)
Perl, Ruby, Python, etc.: byte array

The initialization vector can also be set via the SetEncodedIV method. It allows you to pass the IV bytes as an encoded string using Hex, Base64, etc.

Question #2

If no IV is set, what is the default IV? In our code we weren’t setting the IV, only the key. What would our IV be in this case?

Answer:
The default IV is all zero’s (i.e. null bytes).

Question:
Can the Chilkat library be used to decrypt a large file (<10 Gb) stored on the Hard disk to a memory buffer ?
We are using XP 64 bit computer.
Is there any size limitation ?
What is the typical decryption time (10Gb File using 1024 bit private key)?
If we want to deploy the application do we have to pay additional royalties ?

Answers
First for some quick answers, then I’ll describe how you would go about decrypting a 10GB encrypted file.

1) Yes, it is possible to decrypt a 10GB file into memory (see more below).
2) Yes, 64-bit Windows OS is supported.
3) There are no size limitations.
4) When you say “1024 bit private key” you’re implying public-key encryption (i.e. RSA). You would never use RSA encryption/decryption directly with a large amount of data — it would take a LONG LONG time. RSA is typically used to encrypt/decrypt symmetric keys for bulk encryption algorithms such as AES, Blowfish, etc., and these are the algorithms that should be used when encrypting/decrypting large amounts of data. Decrypting a 10GB file using AES would probably take 10% longer than simply reading 10GB into memory. In other words, it’s a fast enough algorithm that the bulk of the time required is simply getting the data from disk into memory.
5) The Chilkat licensing is royalty-free, which means your application may be deployed and it may included any Chilkat DLLs without requiring the payment of royalties.

How to Decrypt a Large File into Memory

There are properties for decrypting data chunk-by-chunk: FirstChunk and LastChunk. By default, both are true. This means that any call to any encrypt or decrypt method is such that the data is both the first and last chunk (i.e. it’s the entire amount of data to be encrypted/decrypted).

You may write code that reads your 10GB file chunk-by-chunk (any size chunk is fine) and pass it to the appropriate decrypt method, such as DecryptBytes. For the very first call you would set FirstChunk = true, but leave LastChunk = false. For the 2nd call up to the next-to-last call, set both FirstChunk and LastChunk = false (i.e. these are “middle” chunks). For the very last chunk, set LastChunk = true. Each chunk of encrypted data passed to a decrypt method will return a chunk of decrypted data.

Here’s a new example:

ASP: Encrypt URL Query Parameters
SQL Server: Encrypt URL Query Parameters
C#: Encrypt URL Query Parameters
MFC: Encrypt URL Query Parameters
Delphi: Encrypt URL Query Parameters
Visual FoxPro: Encrypt URL Query Parameters
Java: Encrypt URL Query Parameters
Perl: Encrypt URL Query Parameters
PHP: Encrypt URL Query Parameters
Python: Encrypt URL Query Parameters
Ruby: Encrypt URL Query Parameters
VB.NET: Encrypt URL Query Parameters
Visual Basic: Encrypt URL Query Parameters
VBScript: Encrypt URL Query Parameters

This C# example demonstrates how to use Chilkat.Crypt2 to encrypt and decrypting using the .NET FileStream class:

    Chilkat.Crypt2 crypt = new Chilkat.Crypt2();
    bool success = crypt.UnlockComponent("Anything for 30-day trial");
    if (!success)
    {
        MessageBox.Show(crypt.LastErrorText);
        return;
    }

    crypt.CryptAlgorithm = "aes";
    crypt.CipherMode = "cbc";
    crypt.KeyLength = 128;

    crypt.SetEncodedIV("0000000000000000", "hex");
    crypt.SetEncodedKey("abcdefghijklmnop", "ascii");

    // Open input and output files as file streams...
    FileStream fsIn = File.OpenRead("hamlet.xml");
    FileStream fsOut = File.Create("encrypted.dat");

    crypt.FirstChunk = true;
    crypt.LastChunk = false;
    byte [] encryptedChunk;

    // Encrypt the stream in 1024 byte chunks.
    byte[] b = new byte[1024];

    int n;
    while ((n = fsIn.Read(b, 0, b.Length)) > 0)
    {
        if (n < b.Length)
        {
            // Don't encrypt the full 1024 bytes, only the amount read...
            byte[] tmp = new byte[n];
            int i;
            for (i = 0; i < n; i++) tmp[i] = b[i];
            encryptedChunk = crypt.EncryptBytes(tmp);
        }
        else
        {
            encryptedChunk = crypt.EncryptBytes(b);
        }

        fsOut.Write(encryptedChunk, 0, encryptedChunk.Length);
        crypt.FirstChunk = false;
    }
    fsIn.Close();

    // Flush any remaining encrypted data.
    crypt.LastChunk = true;
    byte[] empty = { };
    encryptedChunk = crypt.EncryptBytes(empty);
    if (encryptedChunk.Length > 0)
    {
        fsOut.Write(encryptedChunk, 0, encryptedChunk.Length);
    }
    fsOut.Close();


    // Now decrypt in chunks.  The decryptor must know when the last
    // block is being processed so it may unpad it correctly.

    System.IO.FileInfo fi = new System.IO.FileInfo("encrypted.dat");
    long fileSize = fi.Length;
    int numChunks = (int)fileSize / b.Length;

    fsIn = File.OpenRead("encrypted.dat");
    fsOut = File.Create("decrypted.xml");

    crypt.FirstChunk = true;
    crypt.LastChunk = false;
    byte[] decryptedChunk;

    int idx;
    for (idx = 0; idx <= numChunks; idx++)
    {
        n = fsIn.Read(b, 0, b.Length);

        // Is this the last chunk?
        if (idx == numChunks)
        {
            // Decrypt only the amount read...
            byte[] lastBlock = new byte[n];
            int i;
            for (i = 0; i < n; i++) lastBlock[i] = b[i];
            crypt.LastChunk = true;
            decryptedChunk = crypt.DecryptBytes(lastBlock);
        }
        else
        {
            decryptedChunk = crypt.DecryptBytes(b);
        }

        fsOut.Write(decryptedChunk, 0, decryptedChunk.Length);
        crypt.FirstChunk = false;
    }
    fsIn.Close();
    fsOut.Close();

    MessageBox.Show("Finished!");