Export (0) Print
Expand All

4.8 Java Code to Encrypt and Decrypt a Sample Client Random

The following Java code illustrates how to encrypt and decrypt with RSA.

import java.math.BigInteger;

public class RdpRsaEncrypt
{
    //
    // Print out the contents of a byte array in hexadecimal.
    //
    private static void PrintBytes(
        byte[] bytes
        )
    {
        int cBytes = bytes.length;
        int iByte = 0;

        for (;;) {
            for (int i = 0; i < 8; i++) {
                String hex = Integer.toHexString(bytes[iByte++] & 0xff);
                if (hex.length() == 1) {
                    hex = "0" + hex;
                }

                System.out.print("0x" + hex + " ");
                if (iByte >= cBytes) {
                    System.out.println();
                    return;
                }
            }
            System.out.println();
        }
    }

    //
    // Reverse the order of the values in a byte array.
    //
    public static void ReverseByteArray(
        byte[] array
        )
    {
        int i, j;
        byte temp;

        for (i = 0, j = array.length - 1; i < j; i++, j--) {
            temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }        
    }

    //
    // Use RSA to encrypt data.
    //
    public static byte[] RsaEncrypt(
        byte[] modulusBytes,
        byte[] exponentBytes,
        byte[] dataBytes
        )
    {
        //
        // Reverse the passed in byte arrays and then use these to 
        // create the BigIntegers for the RSA computation.
        //
        ReverseByteArray(modulusBytes);
        ReverseByteArray(exponentBytes);
        ReverseByteArray(dataBytes);

        BigInteger modulus = new BigInteger(
            1, 
            modulusBytes
            );
        BigInteger exponent = new BigInteger(
            1, 
            exponentBytes
            );
        BigInteger data = new BigInteger(
            1, 
            dataBytes
            );

        //
        // Perform RSA encryption: 
        // ciphertext = plaintext^exponent % modulus.
        //
        BigInteger cipherText = data.modPow(
            exponent, 
            modulus
            );

        //
        // Reverse the generated ciphertext.
        //
        byte[] cipherTextBytes = cipherText.toByteArray();
        ReverseByteArray(cipherTextBytes);

        //
        // Undo the reversal of the passed in byte arrays.
        //
        ReverseByteArray(modulusBytes);
        ReverseByteArray(exponentBytes);
        ReverseByteArray(dataBytes);

        return cipherTextBytes;
    }
   
    //
    // Use RSA to decrypt data.
    //
    public static byte[] RsaDecrypt(
        byte[] modulusBytes,
        byte[] privateExponentBytes,
        byte[] encryptedDataBytes
        )
    {
        //
        // Reverse the passed in byte arrays and then use these to 
        // create the BigIntegers for the RSA computation.
        //
        ReverseByteArray(modulusBytes);
        ReverseByteArray(privateExponentBytes);
        ReverseByteArray(encryptedDataBytes);

        BigInteger modulus = new BigInteger(
            1, 
            modulusBytes
            );
        BigInteger privateExponent = new BigInteger(
            1, 
            privateExponentBytes
            );
        BigInteger encryptedData = new BigInteger(
            1, 
            encryptedDataBytes
            );

        //
        // Perform RSA encryption: 
        // plaintext = ciphertext^privateExponent % modulus.
        //
        BigInteger decryptedData = encryptedData.modPow(
            privateExponent, 
            modulus
            );

        //
        // Reverse the generated plaintext.
        //
        byte[] decryptedDataBytes = decryptedData.toByteArray();
        ReverseByteArray(decryptedDataBytes);

        //
        // Undo the reversal of the passed in byte arrays.
        //
        ReverseByteArray(modulusBytes);
        ReverseByteArray(privateExponentBytes);
        ReverseByteArray(encryptedDataBytes);

        return decryptedDataBytes;
    }

    //
    // Main routine.
    //
    public static void main(
        String[] args
        )
    {
        //
        // Modulus bytes obtained straight from the wire in the 
        // proprietary certificate (in little endian format). 
        // This is for a 512-bit key set.
        //
        byte[] modulusBytes = 
        {        
            (byte) 0x37, (byte) 0xa8, (byte) 0x70, (byte) 0xfe, 
            (byte) 0x9a, (byte) 0xb9, (byte) 0xa8, (byte) 0x54,
            (byte) 0xcb, (byte) 0x98, (byte) 0x79, (byte) 0x44, 
            (byte) 0x7a, (byte) 0xb9, (byte) 0xeb, (byte) 0x38,
            (byte) 0x06, (byte) 0xea, (byte) 0x26, (byte) 0xa1, 
            (byte) 0x47, (byte) 0xea, (byte) 0x19, (byte) 0x70,
            (byte) 0x5d, (byte) 0xf3, (byte) 0x52, (byte) 0x88, 
            (byte) 0x70, (byte) 0x21, (byte) 0xb5, (byte) 0x9e,
            (byte) 0x50, (byte) 0xb4, (byte) 0xe1, (byte) 0xf5, 
            (byte) 0x1a, (byte) 0xd8, (byte) 0x2d, (byte) 0x51,
            (byte) 0x4d, (byte) 0x1a, (byte) 0xad, (byte) 0x79, 
            (byte) 0x7c, (byte) 0x89, (byte) 0x46, (byte) 0xb0,
            (byte) 0xcc, (byte) 0x66, (byte) 0x74, (byte) 0x02, 
            (byte) 0xd8, (byte) 0x28, (byte) 0x5d, (byte) 0x9d,
            (byte) 0xd7, (byte) 0xca, (byte) 0xfc, (byte) 0x60, 
            (byte) 0x0f, (byte) 0x38, (byte) 0xf9, (byte) 0xb3
        };

        //
        // Exponent bytes (in little endian order) obtained straight 
        // from the wire (in the proprietary certificate).
        //
        byte[] exponentBytes = 
        {        
            (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00
        };

        //
        // Private exponent of the private key generated by the 
        // server (in little endian format).
        //
        byte[] privateExponentBytes = 
        {
            (byte) 0xc1, (byte) 0x07, (byte) 0xe7, (byte) 0xd4, 
            (byte) 0xd3, (byte) 0x38, (byte) 0x8d, (byte) 0x36,
            (byte) 0xf5, (byte) 0x9e, (byte) 0x8b, (byte) 0x96, 
            (byte) 0x0d, (byte) 0x55, (byte) 0x65, (byte) 0x08,
            (byte) 0x28, (byte) 0x25, (byte) 0xa3, (byte) 0x2e, 
            (byte) 0xc7, (byte) 0x68, (byte) 0xd6, (byte) 0x44,
            (byte) 0x85, (byte) 0x2d, (byte) 0x32, (byte) 0xf6, 
            (byte) 0x72, (byte) 0xa8, (byte) 0x9b, (byte) 0xba,
            (byte) 0x5e, (byte) 0x82, (byte) 0x82, (byte) 0xf0, 
            (byte) 0x5c, (byte) 0x0c, (byte) 0xeb, (byte) 0x6b,
            (byte) 0x12, (byte) 0x6a, (byte) 0xa7, (byte) 0x45, 
            (byte) 0x15, (byte) 0xce, (byte) 0x41, (byte) 0xe0,
            (byte) 0x03, (byte) 0xe5, (byte) 0xe6, (byte) 0x6d, 
            (byte) 0xdf, (byte) 0xfd, (byte) 0x58, (byte) 0x61,
            (byte) 0x0b, (byte) 0x07, (byte) 0xa4, (byte) 0x7b, 
            (byte) 0xb3, (byte) 0xf3, (byte) 0x71, (byte) 0x94
        };

        //
        // Sample 32-byte client random.
        //
        byte[] clientRandomBytes = 
        {
            (byte) 0xff, (byte) 0xee, (byte) 0x00, (byte) 0x00, 
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xff
        };

        System.out.println("Client random:");
        PrintBytes(clientRandomBytes);

        //
        // Perform encryption.
        //
        byte[] encryptedClientRandomBytes = RsaEncrypt(
            modulusBytes,
            exponentBytes,
            clientRandomBytes
            );        

        System.out.println("Encrypted client random:");
        PrintBytes(encryptedClientRandomBytes);

        //
        // Perform decryption.
        //
        byte[] decryptedClientRandomBytes = RsaDecrypt(
            modulusBytes,
            privateExponentBytes,
            encryptedClientRandomBytes
            );        

        System.out.println("Decrypted client random:");
        PrintBytes(decryptedClientRandomBytes);
    }
};
 
Show:
© 2014 Microsoft