1

I'm trying to Store ECIES num0 PrivateKey with DEREncodePrivateKey to a std::string and reload it in num1 PrivateKey Object for testing. Problem is when key is loaded with BERDecodePrivateKey in second PrivateKey object it can't be validated (also tested encryption and decrypting without validation and didn't decrypt )

here's the code

    using namespace CryptoPP;
        CryptoPP::AutoSeededRandomPool prng;

        ECIES<ECP>::PrivateKey pp; 
        pp.Initialize(prng, ASN1::secp256k1());
/* returns true*/
        bool val=pp.Validate(prng, 3);

        std::string saves;
        StringSink savesink(saves);
        pp.DEREncodePrivateKey(savesink);
/*additional unnecessary steps to make sure the key is written completely */
        savesink.MessageEnd();
        savesink.Flush(true);   

        ECIES<ECP>::PrivateKey pro;
        StringSource savesSource(saves, true);
        pro.BERDecodePrivateKey(savesSource,true,savesSource.MaxRetrievable());
/*here the exception is thrown */
        pro.ThrowIfInvalid(prng, 3);
emaditaj
  • 117
  • 9
  • It seems that the validation is likely just comparing the *public key calculated from the private key* with the public key. Now, the public key is usually not present in the private key encoding as it is easy to calculate. So that would make this a very dangerous test indeed, and it likely fails because of this. You may just have a problem with encryption / decryption in other words. Could you show a base 64 encoding of your DER encoded private key? – Maarten Bodewes Jan 14 '20 at 17:06
  • I'm also wondering if `true` should be in there, but I'm not sure on that either. `true` might not be true... – Maarten Bodewes Jan 14 '20 at 17:09
  • @Maarten-reinstateMonica what title you think suits this post ?. for the two "true"s in StringSource and BERDecodePrivateKey and i've tested , they both throw exception if false is set, for StringSource , i've replaced with ByteQueue and StringStore, no difference i'll give a hex/base64 DER encoded key key in next comment, but the keys is generated with Crypto++ itself in the same source file so can't have any problem – emaditaj Jan 14 '20 at 18:54
  • @Maarten-reinstateMonica here's a hex-DER encoded privatekey :: 30250201010420DE6C53FED379779A5974E6E67DC10A987EBB6C99AFEBBCA80FEF6E8E213F5EF9 encryption works , and decryption works well if i export the key using other methos like SAVE() / LOAD() or BEREncode/BERDecode , only fails with DEREncodePrivateKey /BERDecodePrivateKey thanks for helping – emaditaj Jan 14 '20 at 19:06
  • OK, so your DER encoded key consist of a SEQUENCE with an INTEGER valued 1 for the version and an OCTET STRING with just the private key value, see [here](https://lapo.it/asn1js/#MCUCAQEEIN5sU_7TeXeaWXTm5n3BCph-u2yZr-u8qA_vbo4hP175). It definitely doesn't contain the parameters *or the curve* name or OID, and if I look at the code, there is no way that `pro` knows the curve either. Why do you need this specific format? – Maarten Bodewes Jan 14 '20 at 21:31
  • @MaartenBodewes first wanted to use it because this format has lowwer size (bytes count) than orginal key format , but later found out i can use private exponent of private key for saving privateky and public point of publickey for saving public key , they allocate the lowest size ... i still just wondering why this not working , the documentation at crypt++ wiki has a working example for rsa , and indicates that "false" should be changed to "ture" for ecc to work ,.. i guessed the OID of cure is unknown in format and tried to specify it but found no function for that in the ECIES class – emaditaj Jan 15 '20 at 05:35
  • @MaartenBodewes i think this a bug in cryptopp or somehow i should determine OID for cryptopp (and don't know how), anyway thanks for helping – emaditaj Jan 15 '20 at 09:52
  • I agree that it may be a bug, because you would expect some kind of OID in there that indicates the parameters used. Especially since there is a version integer (if that's what it is). Better file a bug report and see what they say. Note that DER *by itself* is not a specific *structured* format, so I'd be very reluctant to use it over other, better described formats. – Maarten Bodewes Jan 15 '20 at 14:16

1 Answers1

0

finally found what the problem is as @maarten-bodewes mentioned in comment the DER encoded private exponent doesn't determine the curve OID for the privateKey Object , so before BER Decoding and importing key we need to somehow determine the OID for the Object; the simplest way is to determine it when Initializing new Object above code changes to :

ECIES<ECP>::PrivateKey pro;
    StringSource savesSource(saves, true);
    auto rett = savesSource.MaxRetrievable();
    pro.Initialize(prng, ASN1::secp256k1());
    pro.BERDecodePrivateKey(savesSource,true,savesSource.MaxRetrievable());

also you AccessGroupParameters().Initialize(/*OID*/); or Initialize(/*OID*/) for existing object

emaditaj
  • 117
  • 9