示例#1
0
  void CTwofishModule::setKey(Tools::CSecureString const &rUserKey, Tools::CSecureMemory const &rGeneratedKey)
  {
  	mKey.allocate(gKeySize);

  	size_t Iterations = gPasswordIterations;
  	if (rGeneratedKey == gGenericSalt)
  	{
  		Iterations = gPasswordIterationsWithoutSalt;
  	}

    PKCS5_PBKDF2_HMAC<SHA256> KeyGenerator;
    KeyGenerator.DeriveKey(
    		&mKey[0],
				mKey.getSize(),
				0x00,
				reinterpret_cast<byte const *>(&rUserKey[0]),
				(unsigned int)rUserKey.getSize(),
				&rGeneratedKey[0],
				(unsigned int)rGeneratedKey.getSize(),
				(unsigned int)Iterations);

    ASSERT(mKey.getSize() == gKeySize);

  	return;
  }
示例#2
0
Encryptor::Encryptor(const std::string& pass, const std::string& theSalt) {
	// Initialize the random pool
	AutoSeededRandomPool prng;

	Encryptor::byteString passphrase;
	passphrase.assign(pass.begin(), pass.end());
	Encryptor::byteString salt;
	salt.assign(theSalt.begin(), theSalt.end());


	PKCS5_PBKDF2_HMAC<CryptoPP::SHA512> passToKey;
	key = new byte[AES_SIZE];
	passToKey.DeriveKey(key, AES_SIZE, '\0', passphrase.c_str(),
			passphrase.size(), salt.c_str(), salt.size(), ITERATIONS);

	// prng.GenerateBlock(key, sizeof(key));

}
示例#3
0
ConstBufferPtr
SecTpm::exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& passwordStr)
{
  using namespace CryptoPP;

  uint8_t salt[8] = {0};
  uint8_t iv[8] = {0};

  // derive key
  if (!generateRandomBlock(salt, 8) || !generateRandomBlock(iv, 8))
    BOOST_THROW_EXCEPTION(Error("Cannot generate salt or iv"));

  uint32_t iterationCount = 2048;

  PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
  size_t derivedLen = 24; // For DES-EDE3-CBC-PAD
  byte derived[24] = {0};
  byte purpose = 0;

  try {
    keyGenerator.DeriveKey(derived, derivedLen, purpose,
                           reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
                           salt, 8, iterationCount);
  }
  catch (const CryptoPP::Exception& e) {
    BOOST_THROW_EXCEPTION(Error("Cannot derived the encryption key"));
  }

  // encrypt
  CBC_Mode< DES_EDE3 >::Encryption e;
  e.SetKeyWithIV(derived, derivedLen, iv);

  ConstBufferPtr pkcs8PrivateKey = exportPrivateKeyPkcs8FromTpm(keyName);

  if (pkcs8PrivateKey == nullptr)
    BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #1"));

  OBufferStream encryptedOs;
  try {
    StringSource stringSource(pkcs8PrivateKey->buf(), pkcs8PrivateKey->size(), true,
                              new StreamTransformationFilter(e, new FileSink(encryptedOs)));
  }
  catch (const CryptoPP::Exception& e) {
    BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #2"));
  }

  // encode
  Oid pbes2Id("1.2.840.113549.1.5.13");
  Oid pbkdf2Id("1.2.840.113549.1.5.12");
  Oid pbes2encsId("1.2.840.113549.3.7");

  OBufferStream pkcs8Os;
  try {
    FileSink sink(pkcs8Os);

    // EncryptedPrivateKeyInfo ::= SEQUENCE {
    //   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
    //   encryptedData        OCTET STRING }
    DERSequenceEncoder encryptedPrivateKeyInfo(sink);
    {
      // EncryptionAlgorithmIdentifier ::= SEQUENCE {
      //   algorithm      OBJECT IDENTIFIER {{PBES2-id}},
      //   parameters     SEQUENCE {{PBES2-params}} }
      DERSequenceEncoder encryptionAlgorithm(encryptedPrivateKeyInfo);
      {
        pbes2Id.encode(encryptionAlgorithm);
        // PBES2-params ::= SEQUENCE {
        //   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
        //   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
        DERSequenceEncoder pbes2Params(encryptionAlgorithm);
        {
          // AlgorithmIdentifier ::= SEQUENCE {
          //   algorithm      OBJECT IDENTIFIER {{PBKDF2-id}},
          //   parameters     SEQUENCE {{PBKDF2-params}} }
          DERSequenceEncoder pbes2KDFs(pbes2Params);
          {
            pbkdf2Id.encode(pbes2KDFs);
            // AlgorithmIdentifier ::= SEQUENCE {
            //   salt           OCTET STRING,
            //   iterationCount INTEGER (1..MAX),
            //   keyLength      INTEGER (1..MAX) OPTIONAL,
            //   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
            DERSequenceEncoder pbkdf2Params(pbes2KDFs);
            {
              DEREncodeOctetString(pbkdf2Params, salt, 8);
              DEREncodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
            }
            pbkdf2Params.MessageEnd();
          }
          pbes2KDFs.MessageEnd();

          // AlgorithmIdentifier ::= SEQUENCE {
          //   algorithm   OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
          //   parameters  OCTET STRING} {{iv}} }
          DERSequenceEncoder pbes2Encs(pbes2Params);
          {
            pbes2encsId.encode(pbes2Encs);
            DEREncodeOctetString(pbes2Encs, iv, 8);
          }
          pbes2Encs.MessageEnd();
        }
        pbes2Params.MessageEnd();
      }
      encryptionAlgorithm.MessageEnd();

      DEREncodeOctetString(encryptedPrivateKeyInfo,
                           encryptedOs.buf()->buf(), encryptedOs.buf()->size());
    }
    encryptedPrivateKeyInfo.MessageEnd();

    return pkcs8Os.buf();
  }
  catch (const CryptoPP::Exception& e) {
    BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #3"));
  }
}
示例#4
0
bool
SecTpm::importPrivateKeyPkcs5IntoTpm(const Name& keyName,
                                     const uint8_t* buf, size_t size,
                                     const std::string& passwordStr)
{
  using namespace CryptoPP;

  Oid pbes2Id;
  Oid pbkdf2Id;
  SecByteBlock saltBlock;
  uint32_t iterationCount;
  Oid pbes2encsId;
  SecByteBlock ivBlock;
  SecByteBlock encryptedDataBlock;

  try {
    // decode some decoding processes are not necessary for now,
    // because we assume only one encryption scheme.
    StringSource source(buf, size, true);

    // EncryptedPrivateKeyInfo ::= SEQUENCE {
    //   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
    //   encryptedData        OCTET STRING }
    BERSequenceDecoder encryptedPrivateKeyInfo(source);
    {
      // EncryptionAlgorithmIdentifier ::= SEQUENCE {
      //   algorithm      OBJECT IDENTIFIER {{PBES2-id}},
      //   parameters     SEQUENCE {{PBES2-params}} }
      BERSequenceDecoder encryptionAlgorithm(encryptedPrivateKeyInfo);
      {
        pbes2Id.decode(encryptionAlgorithm);
        // PBES2-params ::= SEQUENCE {
        //   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
        //   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
        BERSequenceDecoder pbes2Params(encryptionAlgorithm);
        {
          // AlgorithmIdentifier ::= SEQUENCE {
          //   algorithm      OBJECT IDENTIFIER {{PBKDF2-id}},
          //   parameters     SEQUENCE {{PBKDF2-params}} }
          BERSequenceDecoder pbes2KDFs(pbes2Params);
          {
            pbkdf2Id.decode(pbes2KDFs);
            // AlgorithmIdentifier ::= SEQUENCE {
            //   salt           OCTET STRING,
            //   iterationCount INTEGER (1..MAX),
            //   keyLength      INTEGER (1..MAX) OPTIONAL,
            //   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
            BERSequenceDecoder pbkdf2Params(pbes2KDFs);
            {
              BERDecodeOctetString(pbkdf2Params, saltBlock);
              BERDecodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
            }
            pbkdf2Params.MessageEnd();
          }
          pbes2KDFs.MessageEnd();

          // AlgorithmIdentifier ::= SEQUENCE {
          //   algorithm   OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
          //   parameters  OCTET STRING} {{iv}} }
          BERSequenceDecoder pbes2Encs(pbes2Params);
          {
            pbes2encsId.decode(pbes2Encs);
            BERDecodeOctetString(pbes2Encs, ivBlock);
          }
          pbes2Encs.MessageEnd();
        }
        pbes2Params.MessageEnd();
      }
      encryptionAlgorithm.MessageEnd();

      BERDecodeOctetString(encryptedPrivateKeyInfo, encryptedDataBlock);
    }
    encryptedPrivateKeyInfo.MessageEnd();
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
  size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
  byte derived[24] = {0};
  byte purpose = 0;

  try {
    keyGenerator.DeriveKey(derived, derivedLen,
                           purpose,
                           reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
                           saltBlock.BytePtr(), saltBlock.size(),
                           iterationCount);
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  //decrypt
  CBC_Mode< DES_EDE3 >::Decryption d;
  d.SetKeyWithIV(derived, derivedLen, ivBlock.BytePtr());

  OBufferStream privateKeyOs;
  try {
    StringSource encryptedSource(encryptedDataBlock.BytePtr(), encryptedDataBlock.size(), true,
                                 new StreamTransformationFilter(d,  new FileSink(privateKeyOs)));
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  if (!importPrivateKeyPkcs8IntoTpm(keyName,
                                    privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()))
    return false;

  // determine key type
  StringSource privateKeySource(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size(), true);

  KeyType publicKeyType = KeyType::NONE;
  SecByteBlock rawKeyBits;
  // PrivateKeyInfo ::= SEQUENCE {
  //   INTEGER,
  //   SEQUENCE,
  //   OCTECT STRING}
  BERSequenceDecoder privateKeyInfo(privateKeySource);
  {
    uint32_t versionNum;
    BERDecodeUnsigned<uint32_t>(privateKeyInfo, versionNum, INTEGER);
    BERSequenceDecoder sequenceDecoder(privateKeyInfo);
    {
      Oid keyTypeOid;
      keyTypeOid.decode(sequenceDecoder);
      if (keyTypeOid == oid::RSA)
        publicKeyType = KeyType::RSA;
      else if (keyTypeOid == oid::ECDSA)
        publicKeyType = KeyType::EC;
      else
        return false; // Unsupported key type;
    }
  }


  // derive public key
  OBufferStream publicKeyOs;

  try {
    switch (publicKeyType) {
      case KeyType::RSA: {
        RSA::PrivateKey privateKey;
        privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
        RSAFunction publicKey(privateKey);

        FileSink publicKeySink(publicKeyOs);
        publicKey.DEREncode(publicKeySink);
        publicKeySink.MessageEnd();
        break;
      }

      case KeyType::EC: {
        ECDSA<ECP, SHA256>::PrivateKey privateKey;
        privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());

        ECDSA<ECP, SHA256>::PublicKey publicKey;
        privateKey.MakePublicKey(publicKey);
        publicKey.AccessGroupParameters().SetEncodeAsOID(true);

        FileSink publicKeySink(publicKeyOs);
        publicKey.DEREncode(publicKeySink);
        publicKeySink.MessageEnd();
        break;
      }

      default:
        return false;
    }
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  if (!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->size()))
    return false;

  return true;
}
示例#5
0
int main(int argc, char * argv[])
{
	using namespace std;
	using namespace CryptoPP;
	string password = "";
	unsigned int iterations = 1;

	// AutoSeededX917RNG<AES> rng;

	// SecByteBlock iv(AES::BLOCKSIZE);
	// rng.GenerateBlock(iv,iv.size());

	// See NIST SP 800-132 for detailed recommendations on length, generation and
	// format of the salt. This test program will just generate a random one. That
	// might not be sufficient for every application.
	// SecByteBlock pwsalt(AES::DEFAULT_KEYLENGTH);
	// rng.GenerateBlock(pwsalt,pwsalt.size());
	
	SecByteBlock recoveredsalt(AES::DEFAULT_KEYLENGTH);
	StringSource saltDecoder(HEXSALT,true,new HexDecoder(new ArraySink(recoveredsalt, recoveredsalt.size())));
	SecByteBlock recoverediv(AES::BLOCKSIZE);
	StringSource ivDecoder(HEXIV,true,new HexDecoder(new ArraySink(recoverediv, recoverediv.size())));
	

	SecByteBlock derivedkey(AES::DEFAULT_KEYLENGTH);
	
	cout << "Password is " << password << endl;
	cout << "Deriving key from password:"******"Done" << endl;


	string message = "ceciestuntest";
	string ciphertext;

	CBC_Mode<AES>::Encryption aesencryption(derivedkey,derivedkey.size(), recoverediv);
	// encrypt message using key derived above, storing the hex encoded result into ciphertext
	StringSource encryptor(message,true,
		new StreamTransformationFilter(aesencryption, new HexEncoder( new StringSink(ciphertext)))
		);

	// hex encode salt and IV for "transport"
	// string hexsalt, hexiv;
	// ArraySource saltEncoder(pwsalt,pwsalt.size(), true, new HexEncoder(new StringSink(hexsalt)));
	// ArraySource ivEncoder(iv,iv.size(), true, new HexEncoder(new StringSink(hexiv)));
	cout << "Salt: " << HEXSALT << endl;
	cout << "IV: " << HEXIV << endl;
	cout << "Ciphertext: " << ciphertext << endl;
	
	// now recover the plain text given the password, salt, IV and ciphertext
	SecByteBlock recoveredkey(AES::DEFAULT_KEYLENGTH);
	cout << "Re-deriving encryption key based on encoded values above." << endl;
	pbkdf.DeriveKey(recoveredkey, recoveredkey.size(), 0x00, (byte *) password.data(), password.size(),
		recoveredsalt, recoveredsalt.size(), iterations);
	cout << "Done." << endl;
	
	CBC_Mode<AES>::Decryption aesdecryption(recoveredkey, recoveredkey.size(), recoverediv);
	string recoveredtext;
	cout << "-------------------------" << endl;
	ciphertext = "F4302E98C80FC97FE72BA52CFF810B5C";
	cout << "Ciphertext: " << ciphertext << endl;
	
	try {
		StringSource decryptor(ciphertext, true, new HexDecoder(
			new StreamTransformationFilter(aesdecryption, new StringSink(recoveredtext))
			));
	} catch(Exception e) {
		cerr << "\nException raised: " << e.what() << endl;
	}
	cout << "Recovered plaintext value: " << recoveredtext << endl;

	return 0;

}