예제 #1
0
        /*
        ** Name: encode
        **
        ** Description:
        **	Applies the Driver semantics to convert the data and key
        **	into form acceptable to CI and encodes the data using the
        **	key provided.  An optional key mask, CompatCI.CRYPT_SIZE
        **	in length, will be combined with the key if provided.
        **
        ** Input:
        **	key         Encryption key.
        **	mask	    Key mask, may be NULL.
        **	data	    Data to be encrypted.
        **
        ** Output:
        **	None.
        **
        ** Returns:
        **	byte []	    Encrypted data.
        **
        ** History:
        **	 6-May-99 (gordy)
        **	    Created.
        **	22-Sep-99 (gordy)
        **	    Converted parameters to byte arrays for easier processing
        **	    here and to support character set/encoding at a higher level.
        **	21-Apr-00 (gordy)
        **	    Extracted from class AdvanObject.
        **	 6-jul-04 (gordy; ported by thoda04)
        **	    Added key mask.
        */

        public static byte[] encode(byte[] key, byte[] mask, byte[] data)
        {
            byte[] buff = null;
            int    i, j, m, n, blocks;

            lock (KS)
            {
                /*
                ** The key schedule is built from a single CRYPT_SIZE
                ** byte array.  We use the input key to build the byte
                ** array, truncating or duplicating as necessary.
                */
                for (m = n = 0; m < CI.CRYPT_SIZE; m++)
                {
                    if (n >= key.Length)
                    {
                        n = 0;
                    }
                    kbuff[m] = (byte)(key[n++] ^
                                      (mask != null ? mask[m] : (byte)0));
                }

                CI.set(kbuff, KS);

                /*
                ** The data to be encoded must be padded to a multiple
                ** of CRYPT_SIZE bytes.  Random data is used for the
                ** pad, so for strings the null terminator is included
                ** in the data.  A random value is added to each block
                ** so that a given key/data pair does not encode the
                ** same way twice.
                **
                ** The total number of blocks can be calculated from
                ** the string length plus the null terminator divided
                ** into CRYPT_SIZE blocks (with one random byte):
                **	((len+1) + (CRYPT_SIZE-2)) / (CRYPT_SIZE-1)
                ** which can be simplified as:
                **	(len / (CRYPT_SIZE - 1) + 1
                */
                blocks = (data.Length / (CI.CRYPT_SIZE - 1)) + 1;
                buff   = new byte[blocks * CI.CRYPT_SIZE];

                for (i = m = n = 0; i < blocks; i++)
                {
                    buff[m++] = (byte)(rand.Next(256));

                    for (j = 1; j < CI.CRYPT_SIZE; j++)
                    {
                        if (n < data.Length)
                        {
                            buff[m++] = data[n++];
                        }
                        else if (n > data.Length)
                        {
                            buff[m++] = (byte)(rand.Next(256));
                        }
                        else
                        {
                            buff[m++] = 0;                             // null terminator
                            n++;
                        }
                    }
                }

                // encode using obfuscated encode name method
//				CI.encode  (buff, 0, buff.Length, KS, buff, 0);
                CI.toString(buff, 0, buff.Length, KS, buff, 0);
            }

            return(buff);
        }         // encode