weidai11 / cryptopp

free C++ class library of cryptographic schemes
https://cryptopp.com
Other
4.67k stars 1.47k forks source link

Reading RSA keys across platforms between CryptoPP and Python, not in asn1Spec #1205

Closed srinivasramanujan closed 1 year ago

srinivasramanujan commented 1 year ago

I have an application written in C++ using CryptoPP is trying to communicate with Python. If Python generates the Key, CryptoPP won't import it and gives a BER Decode Error, and also if I generate the key in CryptoPP it won't import in Python.

This may also need to be used on Android, IoS, and Java. So I need a method that can work across platforms.

In python I use the rsa module pip install rsa I am using size as 4096 bits

import rsa def generate_keys(name,size): (pub, priv) = rsa.newkeys(size) with open(name + 'pub_key.pem', 'wb') as p: p.write(pub.save_pkcs1('PEM')) with open(name + 'priv_key.pem', 'wb') as p: p.write(priv.save_pkcs1('PEM'))

def load_keys(name): with open(name + 'pub_key.pem', 'rb') as p: pub = rsa.PublicKey.load_pkcs1(p.read()) with open(name + 'priv_key.pem', 'rb') as p: priv = rsa.PrivateKey.load_pkcs1(p.read()) return priv, pub

In CryptoPP I compiled with the PEM Pack and try to load the certificate:

CryptoPP:RSA::PublicKey publicKey1; CryptoPP::FileSource publicKeySource(publicKeyFileName.c_str(), true); CryptoPP::PEM_Load(publicKeySource, publicKey1);

This throws the BER Decode Error.

If instead I generate the keys in CryptoPP and try to use them in Python:

void generate_keys(std::string name) { try{ std::string privateKeyFileName = name+"privatekey.pem"; std::string publicKeyFileName = name+"publickey.pem";

    // Generate private key
    CryptoPP::AutoSeededRandomPool rng;
    CryptoPP::InvertibleRSAFunction params;
    params.GenerateRandomWithKeySize(rng, 4096);
    CryptoPP::RSA::PrivateKey privateKey1(params);

    // Save private key to PEM file
    CryptoPP::FileSink privateKeyFile(privateKeyFileName.c_str());
    CryptoPP::PEM_Save(privateKeyFile, privateKey1);

    // Extract public key from private key
    CryptoPP::RSA::PublicKey publicKey1(privateKey1);

    // Save public key to PEM file
    CryptoPP::FileSink publicKeyFile(publicKeyFileName.c_str());
    CryptoPP::PEM_Save(publicKeyFile, publicKey1);

}
catch(...)
{
    std::cout<<"Error generating PEM keys";
}

}

Traceback (most recent call last): File "pytest.py", line 280, in TEST_PRIV_KEY, TEST_PUB_KEY = load_keys('test') File "pysec.py", line 25, in load_keys pub = rsa.PublicKey.load_pkcs1(p.read()) File "Python\Python39\lib\site-packages\rsa\key.py", line 124, in load_pkcs1 return method(keyfile) File "Python39\lib\site-packages\rsa\key.py", line 330, in _load_pkcs1_pem return cls._load_pkcs1_der(der) File "Python\Python39\lib\site-packages\rsa\key.py", line 297, in _load_pkcs1der (priv, ) = decoder.decode(keyfile, asn1Spec=AsnPubKey()) File "Python\Python39\lib\site-packages\pyasn1\codec\ber\decoder.py", line 1581, in call value, substrate = concreteDecoder.valueDecoder( File "Python\Python39\lib\site-packages\pyasn1\codec\ber\decoder.py", line 609, in valueDecoder component, head = decodeFun(head, componentType, **options) File "Python\Python39\lib\site-packages\pyasn1\codec\ber\decoder.py", line 1618, in call raise error.PyAsn1Error( pyasn1.error.PyAsn1Error: <TagSet object, tags 0:32:16> not in asn1Spec: <Integer schema object, tagSet <TagSet object, tags 0:0:2>>

noloader commented 1 year ago

Please stop asking questions in our bug tracker. Please use the mailing list.