Encrypting Chinese Characters

Why is it the return is blank when encrypting chinese characters?
Here’s a snippet of my code:

  crypt.KeyLength := 256;
  crypt.SecretKey := Password;
  crypt.CryptAlgorithm := 'aes';
  crypt.EncodingMode := 'base64';
  OutPutStr := crypt.EncryptStringENC(StringToEncrypt);


Strings in some programming languages such as Visual Basic, C#, VB.NET, Delphi, Foxpro, etc. should be thought of as objects.  The object contains a string (i.e. a sequence of characters that renders to a sequence of glyphs).  The representation of the string within the object is private — the application shouldn’t care.  For these languages it happens to be Unicode (the 2-byte per char encoding), so the string object is capable of containing characters in any spoken language.  (Of course, just because the string may contain characters in any spoken language doesn’t mean glyphs of any language are renderable, and this is a big problem in older programming languages such as VB6, Delphi, etc. where the visual controls are not capable of mixing glyphs of any language — i.e. they are not Unicode capable controls even though the string data type (i.e. object) holds characters represented internally in Unicode.

OK, back to the main point…

The representation of the string (i.e. the encoding used to represent each character as a sequence of 1 or more bytes) within the string object is private — the application shouldn’t care.   With encryption however, it matters greatly.  Encryption algorithms operate on bytes.  (The same goes for hash algorithms)   Therefore, when you encrypt Chinese characters, did you intend to encrypt 2-byte per char Unicode?  Did you intend to encrypt the utf-8 representation of the characters?  What about the “big5” or “gb2312” character encoding representations?  All would provide different results (of course).

The Crypt.Charset property controls the charset (character encoding) used for encrypting strings.  The string passed to EncryptString* is first converted (internally) to a byte array using the specified character encoding, and then this byte array is encrypted.  The default value for Crypt.Charset is “ANSI”.  In most cases, this is what you expect — you’re expecting a typical European accented character to be represented as a single byte in the default charset of the computer.  This doesn’t work with Chinese (or other Asian languages), or any language that doesn’t match the locale of the computer.  The internal conversion from Unicode to ANSI is dropping the characters where there is no 1-byte/char representation.

The solution:  Set Crypt.Charset equal to the encoding desired.  For Chinese it would be one of the following:  “utf-8”, “Unicode”, “big5”, “gb2312”.

Setting the Initialization Vector for Encryption

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?

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?

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

Decrypt Large Files (10GB)

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.

How to Encrypt URL Query Parameters

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

C# Encrypting/Decrypting with Stream

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)

    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);
            encryptedChunk = crypt.EncryptBytes(b);

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

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

    // 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);
            decryptedChunk = crypt.DecryptBytes(b);

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