Skip to main content
Code Review

Return to Question

edited tags
Link
Der Kommissar
  • 20.3k
  • 4
  • 70
  • 158
added 2 characters in body; edited title
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

encryption Encryption wrapper code

I am writing an encryption class using Crypto++.

The idea is that the client connects using RSA(Encryptencrypt,Decrypt decrypt) with username, password, 32 byte key.

The server will then return using the stream cipher(simEncryptsimEncrypt,simDecryptsimDecrypt) a session idID.

Then any communication between the systems useuses the stream cipher.

  1. Security: Is this a secure way of communicating?
  2. General: Can the code be easily read and formatting?
  • Is this a secure way of communicating.
  1. General:
  • Can the code be easily read and formatting.

A brief explanation of AES and Salsa:

AES: Uses uses two keys. A message encrypted by one is decrypted by the other but can only encrypt a short amount of chracterscharacters (which is why the loop is in the two functions).

Salsa: Given takes a key and IV, it and will encrypt the msgmessage. If If you put the encrypted msgmessage in, it will return msgthe message.

encryption wrapper code

I am writing an encryption class using Crypto++.

The idea is the client connects using RSA(Encrypt,Decrypt) with username, password, 32 byte key.

The server will then return using the stream cipher(simEncrypt,simDecrypt) a session id.

Then any communication between the systems use the stream cipher.

  1. Security:
  • Is this a secure way of communicating.
  1. General:
  • Can the code be easily read and formatting.

A brief explanation of AES and Salsa

AES: Uses two keys. A message encrypted by one is decrypted by the other but can only encrypt a short amount of chracters(which is why the loop is in the two functions)

Salsa: Given a key and IV, it will encrypt the msg. If you put the encrypted msg in, it will return msg.

Encryption wrapper

I am writing an encryption class using Crypto++. The idea is that the client connects using RSA(encrypt, decrypt) with username, password, 32 byte key. The server will then return using the stream cipher(simEncrypt,simDecrypt) a session ID. Then any communication between the systems uses the stream cipher.

  1. Security: Is this a secure way of communicating?
  2. General: Can the code be easily read and formatting?

A brief explanation of AES and Salsa:

AES uses two keys. A message encrypted by one is decrypted by the other but can only encrypt a short amount of characters (which is why the loop is in the two functions).

Salsa takes a key and IV and will encrypt the message. If you put the encrypted message in, it will return the message.

rolling back the code edits, as some edits invalidated answers
Source Link
Simon Forsberg
  • 59.7k
  • 9
  • 157
  • 311
#pragma once

#include <cstdlib>
#include <crypto++/rsa.h>
#include <crypto++/osrng.h>
#include <crypto++/base64.h>
#include <crypto++/files.h>
#include <crypto++/salsa.h>

using namespace CryptoPP;
class encryption {

 //Stream consts
 static const int STREAM_KEY_LENGTH = 32;
 static const int STREAM_IV_LENGTH = 8;
 //AES consts
 static const int MODULUS_BITS = 1024;
 static const int LEFT_PADDING_DIVIDER = 8;
 static const int MAX_ENCRYPTED_MESSAGE_LENGTH = 80;
 static const int MAX_MESSAGE_LENGTH_TO_ENCRYPT =40;

 std::string privFileKeyStr;
 std::string publicFileKeyStr;

 RSAES_OAEP_SHA_Decryptor privKey;
 RSAES_OAEP_SHA_Encryptor pubKey;
 AutoSeededRandomPool rng;
 const byte msgGroupDecryptedLength = 40;

 unsigned int msgGroupEncryptedLength;
 
 //Run salsa on the msg. (Can use the same method for both encrypting and decrypting)
 std::string salsaDo(std::string key, std::string msg, byte iv[STREAM_IV_LENGTH]) {

 //Set up byte arrays for proccess
 byte *plaintextBytes = (byte *)msg.c_str();
 byte *ciphertextBytes = new byte[msg.length()];

 //Setstd::string upSimEncryptDo(std::string key array
 byte*, keyBytesstd::string =strShortString, (byte *iv[8])key.substr(0, STREAM_KEY_LENGTH).c_str();{
 //Peform encryption method byte *plaintextBytes = (byte *)strShortString.c_str();
 byte *ciphertextBytes = new byte[strShortString.length()];
 byte* keyBytes = (byte *)key.substr(0, 32).c_str();

 Salsa20::Encryption salsa;
 salsa.SetKeyWithIV(keyBytes, STREAM_KEY_LENGTH32, iv);
 salsa.ProcessData(ciphertextBytes, plaintextBytes, msgstrShortString.length());
 //return std::string returnStr((const char *)ciphertextBytes, strShortString.length());
 return std::string( salsa.SetKeyWithIV(constkeyBytes, char32, *iv);
 salsa.ProcessData(plaintextBytes, ciphertextBytes, msgstrShortString.length());
 delete ciphertextBytes;
  return returnStr;

 }
public:

 //Use default key locations
 encryption()
 {
 privFileKeyStr = "privkey.txt";
 publicFileKeyStr = "pubkey.txt";
 }
 //Use key locations provided
 encryption(std::string privKeyStr, std::string pubKeyStr) {
 privFileKeyStr = privFileKeyStr;
 publicFileKeyStr = publicFileKeyStr;
 }
 //Generate keys for RSA function
 void generateKeyGenerateKey()
 {
 //CreateAutoSeededRandomPool Keysrng;
 InvertibleRSAFunction privkey;
 privkey.Initialize(rng, MODULUS_BITS1024);

 //Save private key to file
 Base64Encoder privkeysink(new FileSink(privFileKeyStr.c_str()));
 privkey.DEREncode(privkeysink);
 privkeysink.MessageEnd();
 //Save public key to file
 RSAFunction pubkey(privkey); //Get public key
 Base64Encoder pubkeysink(new FileSink(publicFileKeyStr.c_str()));
 pubkey.DEREncode(pubkeysink);
 pubkeysink.MessageEnd();
 }
 
 //Load keys from files
 void loadKeys() {

 //Load public keyvoid fromLoadKeys() file{

 RSAES_OAEP_SHA_Encryptor lPubKey(
 FileSource(publicFileKeyStr.c_str(), true, new Base64Decoder)
 );
 pubKey = lPubKey;
 //Get encrypted file length
 msgGroupEncryptedLength = (unsigned int)pubKey.CiphertextLength(5);
 //Get private key
 RSAES_OAEP_SHA_Decryptor lPrivKey(
 FileSource(privFileKeyStr.c_str(), true, new Base64Decoder)
 );
 privKey = lPrivKey;
 }
 //Encrypt string using the public key
 std::string encryptEncrypt(std::string strToEncryptstrShortString) {
 std::string encryptedStringBuilderBuilder = "";
 std::string plainMsgGroupstringPart = "";
 //Split string into groups for encryption
 for (unsigned int i = 0; i < (unsigned int)strToEncrypt.size(); i = i + MAX_MESSAGE_LENGTH_TO_ENCRYPT) {

 //Get message group
 for (unsigned int i = 0; i plainMsgGroup< =(unsigned strToEncryptint)strShortString.substrsize(i, MAX_MESSAGE_LENGTH_TO_ENCRYPT); i byte= msgLengthi =+ (byte)plainMsgGroup.size(msgGroupDecryptedLength); {
 //GetstringPart padding= forstrShortString.substr(i, frontmsgGroupDecryptedLength);

 byte randLength = rng.GenerateByte() / LEFT_PADDING_DIVIDER;8;
 byte msgLength = (byte)stringPart.size();

 SecByteBlock randomPadLeft(randLength);
 rng.GenerateBlock(randomPadLeft, randLength);
 std::string randomPadLeftStr((const char*)randomPadLeft.begin(), randomPadLeft.size());
 //Build first part of string
 std::string toEncrypt(1, (unsigned char)randLength);//how big is the padding
 toEncrypt.append(std::string(1, (unsigned char)msgLength)); //how big is the msg
 toEncrypt.append(randomPadLeftStr);
 toEncrypt.append(plainMsgGroupstringPart);

 //Generate right padding
 size_t paddingRight = MAX_ENCRYPTED_MESSAGE_LENGTH80 - toEncrypt.size();
 SecByteBlock randomPadRight(paddingRight);
 rng.GenerateBlock(randomPadRight, paddingRight);
 std::string randomPadRightStr((const char*)randomPadRight.begin(), randomPadRight.size());
 toEncrypt.append(randomPadRightStr);

 //Add right padding to the string
 toEncrypt.append(randomPadRightStr); 
 
 //Get encrypted string
 SecByteBlock sbbCipherText(msgGroupEncryptedLength);
 pubKey.Encrypt(
 rng,
 (byte const*)toEncrypt.data(),
 toEncrypt.size(),
 sbbCipherText.begin());
 //Add the encrypted msg to the builder
 encryptedStringBuilderBuilder.append(std::string((const char*)sbbCipherText.begin(), sbbCipherText.size()));
 }
 
 return encryptedStringBuilder;
 }

 //Decrypt a message using thereturn privateBuilder;
 key }

 std::string decryptDecrypt(std::string strToDecryptstrShortString) {
 
 std::string decryptedBuilder;
 //Split string into msggroups
 for (unsigned int i = 0; i < (unsigned int)strToDecryptstrShortString.size(); i = i + msgGroupEncryptedLength) {
 //Get message group
 std::string msgGroup = strToDecryptstrShortString.substr(i, msgGroupEncryptedLength);
 SecByteBlock sbbCipherText(msgGroupEncryptedLength);
 //Get decrypted group
 privKey.Decrypt(
 rng,
 (byte const*)msgGroup.data(),
 msgGroup.size(),
 sbbCipherText.begin());
 std::string decrypted((const char*)sbbCipherText.begin(), sbbCipherText.size());
 //Get size of msg
 byte leftPaddingSizeind1 = decrypted.at(0);
 byte msgSizeSizeind2 = decrypted.at(1);
 //Add actual msg to the string
 decryptedBuilder.append(decrypted.substr(leftPaddingSizeind1 + 2, msgSizeSizeind2));
 }
 return decryptedBuilder;
 }
 std::string simDecrypt(std::string key, std::string strShortString) {

 //Decrypt a message using salsa
 std::string simDecrypt(std::string key, std::string msg) {
 
 //Split msg into iv and encrypted parts
 std::string ivStr = msg.substr(0, STREAM_IV_LENGTH);
 std::string strToDecrypt = msg.substr(STREAM_IV_LENGTH, msg.size() - STREAM_IV_LENGTH);

 //Preparestd::string ivkeyStr = strShortString.substr(0, 8);
 byte*std::string encryptStr iv = strShortString.substr(byte*)ivStr8, strShortString.c_strsize() - 8);
 //Return decrypted message
 byte* iv return= salsaDo(key, strToDecrypt, ivbyte*)keyStr.c_str();
 return SimEncryptDo(key, encryptStr, iv);
 }
 //Encrypt a message using salsa
 std::string simEncrypt(std::string key, std::string strShortString) {
 
 //Create IV string
  byte iv[STREAM_IV_LENGTH];iv[8];
 rng.GenerateBlock(iv, STREAM_IV_LENGTH8);
 
 //Get encrypted message
 std::string encStr = salsaDo SimEncryptDo(key, strShortString, iv);
 //Add iv string
 std::string returnStr(std::string((char *)iv,STREAM_IV_LENGTH 8));
 returnStr.append(encStr);
 return returnStr;
 }

};
#pragma once

#include <cstdlib>
#include <crypto++/rsa.h>
#include <crypto++/osrng.h>
#include <crypto++/base64.h>
#include <crypto++/files.h>
#include <crypto++/salsa.h>
using namespace CryptoPP;
class encryption {

 //Stream consts
 static const int STREAM_KEY_LENGTH = 32;
 static const int STREAM_IV_LENGTH = 8;
 //AES consts
 static const int MODULUS_BITS = 1024;
 static const int LEFT_PADDING_DIVIDER = 8;
 static const int MAX_ENCRYPTED_MESSAGE_LENGTH = 80;
 static const int MAX_MESSAGE_LENGTH_TO_ENCRYPT =40;

 std::string privFileKeyStr;
 std::string publicFileKeyStr;

 RSAES_OAEP_SHA_Decryptor privKey;
 RSAES_OAEP_SHA_Encryptor pubKey;
 AutoSeededRandomPool rng;
 
 unsigned int msgGroupEncryptedLength;
 
 //Run salsa on the msg. (Can use the same method for both encrypting and decrypting)
 std::string salsaDo(std::string key, std::string msg, byte iv[STREAM_IV_LENGTH]) {

 //Set up byte arrays for proccess
 byte *plaintextBytes = (byte *)msg.c_str();
 byte *ciphertextBytes = new byte[msg.length()];

 //Set up key array
 byte* keyBytes = (byte *)key.substr(0, STREAM_KEY_LENGTH).c_str();
 //Peform encryption method
 Salsa20::Encryption salsa;
 salsa.SetKeyWithIV(keyBytes, STREAM_KEY_LENGTH, iv);
 salsa.ProcessData(ciphertextBytes, plaintextBytes, msg.length());
 //return string return std::string((const char *)ciphertextBytes, msg.length());
 
 }
public:

 //Use default key locations
 encryption()
 {
 privFileKeyStr = "privkey.txt";
 publicFileKeyStr = "pubkey.txt";
 }
 //Use key locations provided
 encryption(std::string privKeyStr, std::string pubKeyStr) {
 privFileKeyStr = privFileKeyStr;
 publicFileKeyStr = publicFileKeyStr;
 }
 //Generate keys for RSA function
 void generateKey()
 {
 //Create Keys
 InvertibleRSAFunction privkey;
 privkey.Initialize(rng, MODULUS_BITS);

 //Save private key to file
 Base64Encoder privkeysink(new FileSink(privFileKeyStr.c_str()));
 privkey.DEREncode(privkeysink);
 privkeysink.MessageEnd();
 //Save public key to file
 RSAFunction pubkey(privkey); //Get public key
 Base64Encoder pubkeysink(new FileSink(publicFileKeyStr.c_str()));
 pubkey.DEREncode(pubkeysink);
 pubkeysink.MessageEnd();
 }
 
 //Load keys from files
 void loadKeys() {

 //Load public key from file
 RSAES_OAEP_SHA_Encryptor lPubKey(
 FileSource(publicFileKeyStr.c_str(), true, new Base64Decoder)
 );
 pubKey = lPubKey;
 //Get encrypted file length
 msgGroupEncryptedLength = (unsigned int)pubKey.CiphertextLength(5);
 //Get private key
 RSAES_OAEP_SHA_Decryptor lPrivKey(
 FileSource(privFileKeyStr.c_str(), true, new Base64Decoder)
 );
 privKey = lPrivKey;
 }
 //Encrypt string using the public key
 std::string encrypt(std::string strToEncrypt) {
 std::string encryptedStringBuilder = "";
 std::string plainMsgGroup = "";
 //Split string into groups for encryption
 for (unsigned int i = 0; i < (unsigned int)strToEncrypt.size(); i = i + MAX_MESSAGE_LENGTH_TO_ENCRYPT) {

 //Get message group
  plainMsgGroup = strToEncrypt.substr(i, MAX_MESSAGE_LENGTH_TO_ENCRYPT); byte msgLength = (byte)plainMsgGroup.size();
 //Get padding for front
 byte randLength = rng.GenerateByte() / LEFT_PADDING_DIVIDER;
 SecByteBlock randomPadLeft(randLength);
 rng.GenerateBlock(randomPadLeft, randLength);
 std::string randomPadLeftStr((const char*)randomPadLeft.begin(), randomPadLeft.size());
 //Build first part of string
 std::string toEncrypt(1, (unsigned char)randLength);//how big is the padding
 toEncrypt.append(std::string(1, (unsigned char)msgLength)); //how big is the msg
 toEncrypt.append(randomPadLeftStr);
 toEncrypt.append(plainMsgGroup);

 //Generate right padding
 size_t paddingRight = MAX_ENCRYPTED_MESSAGE_LENGTH - toEncrypt.size();
 SecByteBlock randomPadRight(paddingRight);
 rng.GenerateBlock(randomPadRight, paddingRight);
 std::string randomPadRightStr((const char*)randomPadRight.begin(), randomPadRight.size());
 //Add right padding to the string
 toEncrypt.append(randomPadRightStr); 
 
 //Get encrypted string
 SecByteBlock sbbCipherText(msgGroupEncryptedLength);
 pubKey.Encrypt(
 rng,
 (byte const*)toEncrypt.data(),
 toEncrypt.size(),
 sbbCipherText.begin());
 //Add the encrypted msg to the builder
 encryptedStringBuilder.append(std::string((const char*)sbbCipherText.begin(), sbbCipherText.size()));
 }
 
 return encryptedStringBuilder;
 }

 //Decrypt a message using the private key
 std::string decrypt(std::string strToDecrypt) {
 
 std::string decryptedBuilder;
 //Split string into msggroups
 for (unsigned int i = 0; i < (unsigned int)strToDecrypt.size(); i = i + msgGroupEncryptedLength) {
 //Get message group
 std::string msgGroup = strToDecrypt.substr(i, msgGroupEncryptedLength);
 SecByteBlock sbbCipherText(msgGroupEncryptedLength);
 //Get decrypted group
 privKey.Decrypt(
 rng,
 (byte const*)msgGroup.data(),
 msgGroup.size(),
 sbbCipherText.begin());
 std::string decrypted((const char*)sbbCipherText.begin(), sbbCipherText.size());
 //Get size of msg
 byte leftPaddingSize = decrypted.at(0);
 byte msgSizeSize = decrypted.at(1);
 //Add actual msg to the string
 decryptedBuilder.append(decrypted.substr(leftPaddingSize + 2, msgSizeSize));
 }
 return decryptedBuilder;
 }
 //Decrypt a message using salsa
 std::string simDecrypt(std::string key, std::string msg) {
 
 //Split msg into iv and encrypted parts
 std::string ivStr = msg.substr(0, STREAM_IV_LENGTH);
 std::string strToDecrypt = msg.substr(STREAM_IV_LENGTH, msg.size() - STREAM_IV_LENGTH);

 //Prepare iv 
 byte* iv = (byte*)ivStr.c_str();
 //Return decrypted message
  return salsaDo(key, strToDecrypt, iv);
 }
 //Encrypt a message using salsa
 std::string simEncrypt(std::string key, std::string strShortString) {
 
 //Create IV string
  byte iv[STREAM_IV_LENGTH];
 rng.GenerateBlock(iv, STREAM_IV_LENGTH);
 
 //Get encrypted message
 std::string encStr = salsaDo(key, strShortString, iv);
 //Add iv string
 std::string returnStr(std::string((char *)iv,STREAM_IV_LENGTH));
 returnStr.append(encStr);
 return returnStr;
 }
};
#pragma once

#include <cstdlib>
#include <crypto++/rsa.h>
#include <crypto++/osrng.h>
#include <crypto++/base64.h>
#include <crypto++/files.h>
#include <crypto++/salsa.h>

using namespace CryptoPP;
class encryption {
 std::string privFileKeyStr;
 std::string publicFileKeyStr;

 RSAES_OAEP_SHA_Decryptor privKey;
 RSAES_OAEP_SHA_Encryptor pubKey;
 AutoSeededRandomPool rng;
 const byte msgGroupDecryptedLength = 40;

 unsigned int msgGroupEncryptedLength;
 std::string SimEncryptDo(std::string key, std::string strShortString, byte iv[8]) {
  byte *plaintextBytes = (byte *)strShortString.c_str();
 byte *ciphertextBytes = new byte[strShortString.length()];
 byte* keyBytes = (byte *)key.substr(0, 32).c_str();

 Salsa20::Encryption salsa;
 salsa.SetKeyWithIV(keyBytes, 32, iv);
 salsa.ProcessData(ciphertextBytes, plaintextBytes, strShortString.length());
 std::string returnStr((const char *)ciphertextBytes, strShortString.length());
  salsa.SetKeyWithIV(keyBytes, 32, iv);
 salsa.ProcessData(plaintextBytes, ciphertextBytes, strShortString.length());
 delete ciphertextBytes;
  return returnStr;

 }
public:
 encryption()
 {
 privFileKeyStr = "privkey.txt";
 publicFileKeyStr = "pubkey.txt";
 }
 
 encryption(std::string privKeyStr, std::string pubKeyStr) {
 privFileKeyStr = privFileKeyStr;
 publicFileKeyStr = publicFileKeyStr;
 }
 void GenerateKey()
 {
 AutoSeededRandomPool rng;
 InvertibleRSAFunction privkey;
 privkey.Initialize(rng, 1024);
 
 Base64Encoder privkeysink(new FileSink(privFileKeyStr.c_str()));
 privkey.DEREncode(privkeysink);
 privkeysink.MessageEnd();
 RSAFunction pubkey(privkey);
 Base64Encoder pubkeysink(new FileSink(publicFileKeyStr.c_str()));
 pubkey.DEREncode(pubkeysink);
 pubkeysink.MessageEnd();
 }
 void LoadKeys() {

 RSAES_OAEP_SHA_Encryptor lPubKey(
 FileSource(publicFileKeyStr.c_str(), true, new Base64Decoder)
 );
 pubKey = lPubKey;
 msgGroupEncryptedLength = (unsigned int)pubKey.CiphertextLength(5);
 RSAES_OAEP_SHA_Decryptor lPrivKey(
 FileSource(privFileKeyStr.c_str(), true, new Base64Decoder)
 );
 privKey = lPrivKey;
 }
 std::string Encrypt(std::string strShortString) {
 std::string Builder = "";
 std::string stringPart = "";
 for (unsigned int i = 0; i < (unsigned int)strShortString.size(); i = i + msgGroupDecryptedLength) {
 stringPart = strShortString.substr(i, msgGroupDecryptedLength);

 byte randLength = rng.GenerateByte() / 8;
 byte msgLength = (byte)stringPart.size();

 SecByteBlock randomPadLeft(randLength);
 rng.GenerateBlock(randomPadLeft, randLength);
 std::string randomPadLeftStr((const char*)randomPadLeft.begin(), randomPadLeft.size());
 std::string toEncrypt(1, (unsigned char)randLength);
 toEncrypt.append(std::string(1, (unsigned char)msgLength));
 toEncrypt.append(randomPadLeftStr);
 toEncrypt.append(stringPart);

 size_t paddingRight = 80 - toEncrypt.size();
 SecByteBlock randomPadRight(paddingRight);
 rng.GenerateBlock(randomPadRight, paddingRight);
 std::string randomPadRightStr((const char*)randomPadRight.begin(), randomPadRight.size());
 toEncrypt.append(randomPadRightStr);

 SecByteBlock sbbCipherText(msgGroupEncryptedLength);
 pubKey.Encrypt(
 rng,
 (byte const*)toEncrypt.data(),
 toEncrypt.size(),
 sbbCipherText.begin());
 Builder.append(std::string((const char*)sbbCipherText.begin(), sbbCipherText.size()));
 }
 
 return Builder;
  }

 std::string Decrypt(std::string strShortString) {
 
 std::string decryptedBuilder;
 for (unsigned int i = 0; i < (unsigned int)strShortString.size(); i = i + msgGroupEncryptedLength) {
 std::string msgGroup = strShortString.substr(i, msgGroupEncryptedLength);
 SecByteBlock sbbCipherText(msgGroupEncryptedLength);

 privKey.Decrypt(
 rng,
 (byte const*)msgGroup.data(),
 msgGroup.size(),
 sbbCipherText.begin());
 std::string decrypted((const char*)sbbCipherText.begin(), sbbCipherText.size());
 byte ind1 = decrypted.at(0);
 byte ind2 = decrypted.at(1);
 decryptedBuilder.append(decrypted.substr(ind1 + 2, ind2));
 }
 return decryptedBuilder;
 }
 std::string simDecrypt(std::string key, std::string strShortString) {

 std::string keyStr = strShortString.substr(0, 8);
 std::string encryptStr = strShortString.substr(8, strShortString.size() - 8);
 byte* iv = (byte*)keyStr.c_str();
 return SimEncryptDo(key, encryptStr, iv);
 }
 std::string simEncrypt(std::string key, std::string strShortString) {
 
 byte iv[8];
 rng.GenerateBlock(iv, 8);
 
 std::string encStr =  SimEncryptDo(key, strShortString, iv);
 std::string returnStr(std::string((char *)iv, 8));
 returnStr.append(encStr);
 return returnStr;
 }

};
added what I am looking for.
Source Link
Catprog
  • 271
  • 1
  • 7
Loading
removed magic numbers, fixed up white lines and added comments to blocks, renamed variables and lowercased the first letter.
Source Link
Catprog
  • 271
  • 1
  • 7
Loading
edited tags
Link
200_success
  • 145.5k
  • 22
  • 190
  • 479
Loading
Source Link
Catprog
  • 271
  • 1
  • 7
Loading
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /