/* Encrypts a string "message" using "key". */ std::string RSA::encryptString(const std::string &message, const Key &key) { //partition the message into biggest possible encryptable chunks const unsigned long int chunkSize(((key.GetModulus().Length() - 2) / 3)); const unsigned long int chunkCount = message.length() / chunkSize; string cypherText; for (unsigned long int i(0); i < chunkCount; i++) { // Get the next chunk. string chunk(message.substr(i * chunkSize, chunkSize)); chunk = RSA::encryptChunk(chunk, key); // Put a ' ' between the chunks so that we can separate them later. cypherText.append(chunk.append(" ")); } // If the last chunk has the same size as the others, we are finished. if (chunkSize * chunkCount == message.length()) return cypherText; // Handle the last chunk. It is smaller than the others. const unsigned long int lastChunkSize = message.length() % chunkSize; string lastChunk(message.substr(chunkCount * chunkSize, lastChunkSize)); lastChunk = RSA::encryptChunk(lastChunk, key); return cypherText.append(lastChunk.append(" ")); }
/* Decrypts a "chunk" (a small part of a message) using "key" */ string RSA::decryptChunk(const BigInt &chunk, const Key &key) { BigInt a = chunk; // The RSA decryption algorithm is a congruence equation. a.SetPowerMod(key.GetExponent(), key.GetModulus()); // Decode the message to a readable form. return RSA::decode(a); }
/* Encrypts a "chunk" (a small part of a message) using "key" */ string RSA::encryptChunk(const string &chunk, const Key &key) { // First encode the chunk, to make sure it is represented as an integer. BigInt a = RSA::encode(chunk); // The RSA encryption algorithm is a congruence equation. a.SetPowerMod(key.GetExponent(), key.GetModulus()); return a.ToString(); }
/* Decrypts a string "message" using "key". */ std::string RSA::decryptString(const std::string &cypherText, const Key &key) { // Partition the cypherText into chunks. They are seperated by ' '. string message; long int i(0), j(0); while ((j = cypherText.find(' ', i)) != -1) { // Get the chunk. BigInt chunk(cypherText.substr(i, j - i)); if (chunk >= key.GetModulus()) throw "Error RSA02: Chunk too large."; // Decrypt the chunk and store the message. string text = RSA::decryptChunk(chunk, key); message.append(text); i = j + 1; } return message; }
/* Throws an exception if "key" is too short to be used. */ void RSA::checkKeyLength(const Key &key) { // Minimum required key length is around 24 bits. (In-house requirement) if (key.GetModulus().Length() < 8) throw "Error RSA01: Keys must be at least 8 digits long."; }