Recovery keys (ECPublicKeyParameters) in C # with BouncyCastle

I generate AsymmetricCipherKeyPair as follows:

string curveName = "P-521"; X9ECParameters ecP = NistNamedCurves.GetByName(curveName); ECDomainParameters ecSpec = new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed()); IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("ECDH"); g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom())); AsymmetricCipherKeyPair aKeyPair = g.GenerateKeyPair(); 

My intention was to extract the public and private keys, and then rebuild the keys later. First I extracted the keys as follows:

 byte[] privateKey = ((ECPrivateKeyParameters)aKeyPair.Private).D.ToByteArray(); byte[] publicKey = ((ECPublicKeyParameters)aKeyPair.Public).Q.GetEncoded(); 

How to update public and private key parameters so that I can use them? In this example, I recreate the private key and sign the array of data bytes.

 public static byte[] SignData(byte[] data, byte[] privateKey) { string curveName = "P-521"; X9ECParameters ecP = NistNamedCurves.GetByName(curveName); ECDomainParameters ecSpec = new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed()); ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA"); BigInteger biPrivateKey = new BigInteger(privateKey); ECPrivateKeyParameters keyParameters = new ECPrivateKeyParameters(biPrivateKey, ecSpec); signer.Init(true, keyParameters); signer.BlockUpdate(data, 0, data.Length); return signer.GenerateSignature(); } 

Although this seems like a real hack, everything works fine. How can I do this with a public key? I set the xxx variable to (ECPublicKeyParameters) aKeyPair.Public, and I can use the code below to verify the signature. Note that I could use xxx directly, but the thing is to serialize xxx and then re-enter, so this code actually converts the xxx variable and creates a new one that is stored in xx. Then I use xx to check (which shows that I can bypass the key).

 var xx = PublicKeyFactory.CreateKey(Org.BouncyCastle.X509.SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(xxx).GetDerEncoded()); ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA"); signer.Init(false, xx); signer.BlockUpdate(data, 0, data.Length); return signer.VerifySignature(signature); 

I was hoping I could create the key (xx) from Q.GetEncoded (), similar to the way I did for the private key.

Is there a better way to rebuild the private key? also using ASN.1 encoding? If so, maybe I should use this instead.

+4
source share
1 answer

I can do it like this:

 string curveName = "P-521"; X9ECParameters ecP = NistNamedCurves.GetByName(curveName); FpCurve c = (FpCurve)ecP.Curve; ECFieldElement x = new FpFieldElement(cQ, xxx.QXToBigInteger()); ECFieldElement y = new FpFieldElement(cQ, xxx.QYToBigInteger()); ECPoint q = new FpPoint(c, x, y); ECPublicKeyParameters xxpk = new ECPublicKeyParameters("ECDH", q, SecObjectIdentifiers.SecP521r1); 

Then I can use xxpk to verify the signature.

Disclaimer: I am not saying that this is the best way to do this, just to make it work!

+2
source

Source: https://habr.com/ru/post/1489397/


All Articles