Hi Leigh, The CFX internally used a Delphi Component TRSA (aecRSA) from TSM Inc. (which is now out f business..). I've read the help file and it doesn't say much about how the strings are encoded. I found the following information in the help manual, not sure if there are any clues in here, I couldn't find any:
"TRSA handles padding of blocks in the encryption and decryption of strings and symmetric keys internally, and the use need not concern himself with passing the correct length string or symmetric key." "The public key consists of a "Modulus" - a large integer which can be used to encrypt data together with the "Exponent". The two parts of the key are separated by a colon. Both parts of the key need to be transmitted, and should not be separated from each other. (See Key Generation)" ========================= Key Generation Prime number generation Producing key pairs is a time consuming process, the length of the process dictated by the difficulty of finding large random numbers. To produce a 2048 bit key, two 1024 bit random numbers have to be found. Even using a number of optimisations, the production of a 2048 bit key can take many minutes on slower systems as large primes become both increasingly rarer and more difficult to check as the length increases. Random number generation is achieved the following steps to give the maximum performance: . A random number is picked of nominally the right length. The LSB (Least Significant Bit) and the MSB (Most Significant Bit) are set to ensure that the number is odd and the expected length. (For RSA to work with the maximum security, the prime numbers should be equal in length). . A sieve of Erastosthenes is created holding the 400 smallest primes. A random number is picked and the lowest and highest bits are set to ensure that it is odd and has the expected number of bits. A window of length 2000, starting at the random number is created, and the small primes struck out using modular arithmetic. Any number left unstruck is a candidate prime. . Each candidate prime, p, is tested using four iterations of a test for primality based on Fermat's theorem, that is: x^(p-1) = 1 mod p for any given prime x. Any candidate prime which passes all four iterations is worth a second look. All primes pass this test and a majority of composites (non-primes) fail. . To make sure we have found a prime, we use the Miller-Rabin test for primality to make sure. This is a probabilistic test, and the certainty of each test is 0.25. Performing 10 of these tests gives a probability of 0.9999990463257 that the chosen number is a prime. This level of certainty is far better than that provided by other products which use PK encryption (e.g. PGP), and corresponds to one failure in every million keys created on average. This certainty factor can be increased by changing a parameter in the key generation process, but should be suitable for all but the very most clinically paranoid of applications. Key generation As soon as we have found two primes, p and q, of the right length, we are able to produce the keys. To do this we need to find an exponent, which is relatively prime to (p-1) and (q-1). We do this with trial and error, picking a small odd starting number and testing it for relative primality with (p-1) and (q-1). The exact value of the exponent and the fact that it is small with regard to the length of the primes is not a risk to the security of the algorithm. Some implementations even work with fixed exponents (e.g. 17 or 65537) which are chosen to allow speed increases. As soon as we have determined the exponent, e, we can create the final keys: e chosen above ('exponent') n = p.q ('Modulus') d = e^(-1) mod ((p-1)(q-1)) ('Inverse') The public key is then e and n, the private key is d. The procedure TRSA.MakeKeyPair performs the above operations and stores the keys internally. To retrieve the keys from TRSA you can use: procedure GetPublicKey(var Exponent: BigNum; var Modulus: BigNum); procedure GetPrivateKey(var Modulus: BigNum; var Inverse: BigNum); The Keys are additionally loaded in base 64 encoded text form into the properties: PublicKey PrivateKey Writing a valid base64 encoded key into the properties PublicKey or PrivateKey loads the internal registers with the corresponding value. ============================================================================ ================ Using TRSA The interface to TRSA is designed to be as simple to use as possible, and should provide you with the tools to perform RSA encryption easily but should remain flexible. Number representations used by TRSA The RSA algorithm uses very long integer values (up to 2048 bits in this version) to achieve the levels of security required by today's applications. The long integers used in the RSA process cannot be handled directly by any processor, meaning that data structures must be used to represent these integers. The internal representation of the long integers (often referred to as 'BigNums') is defined by an array of 32 bit integers. The most challenging part of writing software to perform RSA encryption is in fact the creation of the integer routines which handle the BigNums quickly and safely. The BigNums are available to your programs, as they are defined in the Interface section of the component. You can use a BigNum by simply defining a variable with the type BigNum. The length of the array of 32 bit integers is defined by the constant MAX_DIGITS, which is also defined in the interface section. The individual elements of a BigNum can be accessed using either a byte interface or a word (32 bit) interface. The byte elements of the array can be accessed by the 'Bytes' modifier, while the word elements can be accessed using the 'Contents' modifier: // returns the first byte of the BigNum FirstByte := TempBigNum.Bytes[0]; // returns the first 32 bit word of the BigNum FirstWord := TempBigNum.Contents[0]; You can also access the contents of the bignum to print it or inspect it. For example, if you want to print out the hex representation of the internal private key, the following code will do this: procedure TfrmRSATest.btnGetPrivKeyClick(Sender: TObject); Var TempModulus: BigNum; TempInverse: BigNum; i: Integer; TempString: String; begin // retrieve the public key from TRSA RSA1.GetPrivateKey (TempModulus, TempInverse); // format the inverse for output TempString := ''; // remove the leading zeroes i := MAX_DIGITS-1; while TempInverse.Contents[i] = 0 do begin Dec(i); end; // create the string while i >= 0 do begin TempString := TempString + IntToHex(TempInverse.Contents[i],4); Dec(i); end; // show the hex value ShowMessage(TempString); end; This method of storing the keys is however inconvenient, as the length of the strings can be excessive. For instance, a 2048 bit key is: 2048 bits / 8 = 256 bytes 256 bytes * 2 hex digits = 512 characters long! TRSA offers a more convenient method for handling the strings, using Base64 encoding. Base64 encoding uses a character set which was chosen to only include characters which are transmittable over eMail, so that binary data can be sent without fear that the information will be modified by mail gateways or mail programs. No special characters are included in the Base64 character set, and therefore no translation of the characters will be performed. The Base64 character set uses only the following characters, where each character stands for 6 bits of information: +-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz The same 2048 bit key will take up 2048 / 6 = 341 characters The values in the Loading keys in TRSA Before TRSA can perform any sort of encryption, TRSA must have valid keys (either private or public, depending on the operation to be performed). The following table shows the keys which must be loaded into TRSA for the various operations to be performed: Encryption Public key Decryption Private key Signing Private key Validation Public key The keys which TRSA uses can either be loaded into TRSA from binary representations using the functions SetPublicKey and SetPrivateKey functions. It is assumed that the keys passed using these methods are valid. No further validation is performed before the keys are used, so entering incorrect values here will at very least give incorrect results. Recovering the keys in binary form can be done using the GetPublicKey and GetPrivateKey functions. The methods for loading binary keys is: // set a public key SetPublicKey (Exponent, Modulus); // set a private key SetPrivateKey (Modulus, Inverse); You can also load the keys in string from by writing them directly into the properties. It is assumed that the keys written to the PublicKey and PrivateKey properties are valid, but before accepting them TRSA will check that they have the right format (Base64) and the right length (depending on the current key length). If errors occur during the processing of these values, and exception will be raised. See the Error Handling section for more details. // set a private key try RSA1.PrivateKey := TempPrivKeyString; Except // there was an error ShowMessge('Error setting private key'); End; {try} -----Original Message----- From: Leigh [mailto:cfsearch...@yahoo.com] Sent: March-15-11 2:21 AM To: cf-talk Subject: Re: Old School CFX (TextCrypt) and RSA Encryption > There may be some other jiggery pokery going on however, ... > so I would imagine that you may have to pad the start or end with null > characters to get the full 512 bits. I could be wrong, but it seems like there is more going on than just a simple split, pad with nulls, then base64 decode ... None of the variations I tried seemed to work. Did they give you an example of their public key and along with how its broken down into modulus and public exponent? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Order the Adobe Coldfusion Anthology now! http://www.amazon.com/Adobe-Coldfusion-Anthology/dp/1430272155/?tag=houseoffusion Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:343045 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm