private static final String MERCHANT_PRIVATE_KEY_PKCS8_BASE64 = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgCPSuFr4iSIaQprjj" + "chHPyDu2NXFe0vDBoTpPkYaK9dehRANCAATnaFz/vQKuO90pxsINyVNWojabHfbx" + "9qIJ6uD7Q7ZSxmtyo/Ez3/o2kDT8g0pIdyVIYktCsq65VoQIDWSh2Bdm";
I tried it this way, using PEM_Load:
string ecPriv =
"-----BEGIN EC PRIVATE KEY-----\n"
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgCPSuFr4iSIaQprjj\n"
"chHPyDu2NXFe0vDBoTpPkYaK9dehRANCAATnaFz/vQKuO90pxsINyVNWojabHfbx\n"
"9qIJ6uD7Q7ZSxmtyo/Ez3/o2kDT8g0pIdyVIYktCsq65VoQIDWSh2Bdm\n"
"-----END EC PRIVATE KEY-----\n";
try
{
AutoSeededRandomPool prng2;
CryptoPP::StringSource ss(ecPriv, true);
ECIES<ECP>::PrivateKey privKey;
PEM_Load(ss, privKey);
bool valid = privKey.Validate(prng2, 3);
if(!valid)
std::cerr << "EC private key is not valid" << endl;
cout << "SUCCESS 2222" << endl;
}
catch (const CryptoPP::Exception& ex)
{
std::cerr << ex.what() << endl;
exit (1);
}
And also manually:string PRIV_KEY =
"-----BEGIN EC PRIVATE KEY-----\n"
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgCPSuFr4iSIaQprjj\n"
"chHPyDu2NXFe0vDBoTpPkYaK9dehRANCAATnaFz/vQKuO90pxsINyVNWojabHfbx\n"
"9qIJ6uD7Q7ZSxmtyo/Ez3/o2kDT8g0pIdyVIYktCsq65VoQIDWSh2Bdm\n"
"-----END EC PRIVATE KEY-----\n";
static string HEADER = "-----BEGIN EC PRIVATE KEY-----";
static string FOOTER = "-----END EC PRIVATE KEY-----";
size_t pos1, pos2;
pos1 = PRIV_KEY.find(HEADER);
if(pos1 == string::npos)
throw runtime_error("PEM header not found");
pos2 = PRIV_KEY.find(FOOTER, pos1+1);
if(pos2 == string::npos)
throw runtime_error("PEM footer not found");
// Start position and length
pos1 = pos1 + HEADER.length();
pos2 = pos2 - pos1;
string keystr = PRIV_KEY.substr(pos1, pos2);
// Base64 decode, place in a ByteQueue
ByteQueue queue;
Base64Decoder decoder;
decoder.Attach(new Redirector(queue));
decoder.Put((const byte*)keystr.data(), keystr.length());
decoder.MessageEnd();
try
{
//CryptoPP::RSA::PrivateKey rsaPrivate;
ECIES<ECP>::PrivateKey ePrivate;
ePrivate.BERDecodePrivateKey(queue, false /*paramsPresent*/, queue.MaxRetrievable());
AutoSeededRandomPool prng2;
bool valid = ePrivate.Validate(prng2, 3);
if(!valid)
cerr << "RSA private key is not valid" << endl;
cout << "SUCCESS" << endl;
}
catch (const CryptoPP::Exception& ex)
{
cerr << ex.what() << " BLA_BLA" << endl;
exit (1);
}
But with no luck, always getting:
BER decode error
Rather strange, but another EC key from pem library worked fine for me:-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIMcH2yHJcahaqSB0XdPKr+TotYB38wfV9caILqg9Jj7uoAcGBSuBBAAK
oUQDQgAEX7J/7ZwW1rO3HpoGxpYRv0PyvfeGKAmcXDVz3qJefS3ToGHYZhPVIyBY
i0xlRDP/EwFMilLCA9Rl/bD0E1hzGg==
-----END EC PRIVATE KEY-----
What I'm doing wrong here?
I'm confused, that openssl successfully parse both of the keys.
Hello list,
I'm trying to use cryptopp for implementing small lib which will allow me to integrate with Android Pay.
I have difficulties with loading private key into Crypto++ wich is mentioned in https://developers.google.com/android-pay/integration/gateway-processor-integration#using-openssl-to-generate-and-format-a-keyprivate static final String MERCHANT_PRIVATE_KEY_PKCS8_BASE64 = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgCPSuFr4iSIaQprjj" + "chHPyDu2NXFe0vDBoTpPkYaK9dehRANCAATnaFz/vQKuO90pxsINyVNWojabHfbx" + "9qIJ6uD7Q7ZSxmtyo/Ez3/o2kDT8g0pIdyVIYktCsq65VoQIDWSh2Bdm";
I tried it this way, using PEM_Load:
string ecPriv =
"-----BEGIN EC PRIVATE KEY-----\n"
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgCPSuFr4iSIaQprjj\n"
"chHPyDu2NXFe0vDBoTpPkYaK9dehRANCAATnaFz/vQKuO90pxsINyVNWojabHfbx\n"
"9qIJ6uD7Q7ZSxmtyo/Ez3/o2kDT8g0pIdyVIYktCsq65VoQIDWSh2Bdm\n"
"-----END EC PRIVATE KEY-----\n";
I have difficulties with loading private key into Crypto++ wich is mentioned in https://developers.google.com/android-pay/integration/gateway-processor-integration#using-openssl-to-generate-and-format-a-keyprivate static final String MERCHANT_PRIVATE_KEY_PKCS8_BASE64 = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgCPSuFr4iSIaQprjj" + "chHPyDu2NXFe0vDBoTpPkYaK9dehRANCAATnaFz/vQKuO90pxsINyVNWojabHfbx" + "9qIJ6uD7Q7ZSxmtyo/Ez3/o2kDT8g0pIdyVIYktCsq65VoQIDWSh2Bdm";
I have difficulties with loading private key into Crypto++ wich is mentioned in https://developers.google.com/android-pay/integration/gateway-processor-integration#using-openssl-to-generate-and-format-a-keyprivate static final String MERCHANT_PRIVATE_KEY_PKCS8_BASE64 = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgCPSuFr4iSIaQprjj" + "chHPyDu2NXFe0vDBoTpPkYaK9dehRANCAATnaFz/vQKuO90pxsINyVNWojabHfbx" + "9qIJ6uD7Q7ZSxmtyo/Ez3/o2kDT8g0pIdyVIYktCsq65VoQIDWSh2Bdm";
My bad... I missed that you were already using the PEM Pack.
Try this, it works for me...
I'm trying to use cryptopp for implementing small lib which will allow me to integrate with Android Pay.
ECParameterSpec aasymmetricKeyParams = generateECParameterSpec();
KeyFactory asymmetricKeyFactory = KeyFactory.getInstance(ASYMMETRIC_KEY_TYPE, SECURITY_PROVIDER);
PublicKey ephemeralPublicKey = asymmetricKeyFactory.generatePublic(
new ECPublicKeySpec( ECPointUtil.decodePoint(asymmetricKeyParams.getCurve(), ephemeralPublicKeyBytes), asymmetricKeyParams));
string ephemeralPubKey64 =
"BPhVspn70Zj2Kkgu9t8+ApEuUWsI/zos5whGCQBlgOkuYagOis7"
"qsrcbQrcprjvTZO3XOU+Qbcc28FSgsRtcgQE=";
StringSource ssECPoint(ephemeralPubKey64, true, new Base64Decoder);
DL_GroupParameters_EC<ECP> params(CryptoPP::ASN1::secp256r1());
ECP::Point point;
if (!params.GetCurve().DecodePoint(point, ssECPoint, (size_t)ssECPoint.MaxRetrievable()))
std::cerr << "Invalid decoding" << endl;
ECIES<ECP>::PublicKey ephemeralPubKey;
ephemeralPubKey.Initialize(params, point);
ephemeralPubKey.ThrowIfInvalid(prng, 3);
cout << "Public key appears to be valid" << endl;string ephemeralPubKey64 =
"BPhVspn70Zj2Kkgu9t8+ApEuUWsI/zos5whGCQBlgOkuYagOis7"
"qsrcbQrcprjvTZO3XOU+Qbcc28FSgsRtcgQE=";
StringSource ssECPoint(ephemeralPubKey64, true, new Base64Decoder);
DL_GroupParameters_EC<ECP> params(CryptoPP::ASN1::secp256r1());
ECP::Point point;
if (!params.GetCurve().DecodePoint(point, ssECPoint, (size_t)ssECPoint.MaxRetrievable()))
std::cerr << "Invalid decoding" << endl;
ECIES<ECP>::PublicKey ephemeralPubKey;
ephemeralPubKey.Initialize(params, point);
ephemeralPubKey.ThrowIfInvalid(prng, 3);
cout << "Public key appears to be valid" << endl;But still need to figure out how to pass it to Decryptor
DL_KeyDerivationAlgorithm_P1363<ECP::Point, true /*DHAES_MODE*/, P1363_KDF2<SHA256> > derieveAlgo;
DL_EncryptionAlgorithm_Xor<HMAC<SHA256>, true /*DHAES_MODE*/, true /*BC_COMPAT*/> encAlgo;So now I've got the questions related to KeyDerivationAlgo and EncryptionAlgo.1. According to Bouncy Castle compatability patch and java example as I understand I need to instantiate:DL_KeyDerivationAlgorithm_P1363<ECP::Point, true /*DHAES_MODE*/, P1363_KDF2<SHA256> > derieveAlgo;
DL_EncryptionAlgorithm_Xor<HMAC<SHA256>, true /*DHAES_MODE*/, true /*BC_COMPAT*/> encAlgo;In the documentation they mention DEM2 from ISO 18033-2.Is the encAlgo definition above fully compatible with that?
2. One more thing that I'm missing right now - which params should I store in NameValuePairs?I guess for:- deriviation they should be at least: null sault, info string Android encoded in Ascii.
- encryption algo: zero IV and no padding