I have to implement a protocol where the client sends his EC public key
and my fist step is to generate my own ephemeral EC public/private key
pair and then calculate shared secret, which will be used later to generate session keys. The elliptic curve in question is brainpoolP224r1. Below is my code (with hardcoded values), which either returs wrong result or throws an expection 'The multiplicator cannot be negative'. Any help would be very appreciated.public static byte[] CalculateSharedSecret() { // Public key from the client. var iccPublicKey = "1A4C233D49F62BF7F419EBE6E2B81E936E88A93599BFDDE9205DA4DF984969C62695FD825A73F0207AB2D0CF9D5EF0DAAEA92360628032A0"; // My ephemeral EC key pair. var privateKey = "5744E0ED24B7C374DA05F6EBDD3BFDE0F0E629BF93294279B5F169BD"; var publicKey = "32924227C99ACAA858343C658D08C023316BFB87FE88E22D1F3A7E8D43ADCA39EBEF36904D64BAC677F11ECBEE501C9017808D4FA1AB8988"; // This is the expected result, but my function returns 32FF74B40D904AE021BCB32B43B56C2D1E09752A47BE089CCED33197. var expectedShareSecret = "6CBE1E0F401F55B2479D44921068DCB19445E8A808ACEAE9B8E73505"; // Curve and curve parameters. var curveParameters = TeleTrusTNamedCurves.GetByName("brainpoolp224r1"); var curve = curveParameters.Curve; var curveIdentifier = TeleTrusTObjectIdentifiers.BrainpoolP224R1; // Calculate shared secret. var iccPublicKeyLengthInBytes = iccPublicKey.Length / 2; var iccPublicKeyX = iccPublicKey.Substring(0, iccPublicKeyLengthInBytes); var iccPublicKeyY = iccPublicKey.Substring(iccPublicKeyLengthInBytes); var iccPublicKeyPoint = new ECPublicKeyParameters( "ECDH", new FpPoint( curve, new FpFieldElement(((FpCurve)curve).Q, new BigInteger(Conversions.HexStringToByteArray(iccPublicKeyX))), new FpFieldElement(((FpCurve)curve).Q, new BigInteger(Conversions.HexStringToByteArray(iccPublicKeyY))) ), curveIdentifier ); var spec = new ECDomainParameters(curve, curveParameters.G, curveParameters.N, curveParameters.H); var keyParameters = new ECPrivateKeyParameters(new BigInteger(Conversions.HexStringToByteArray(privateKey)), spec); var agreement = new ECDHBasicAgreement(); agreement.Init(keyParameters); return agreement.CalculateAgreement(iccPublicKeyPoint).ToByteArray(); } |
This might or might not help with the problem that you know about, but it should help with the problem you don't yet know about - e.g. hash the shared secret. This is C#. Adjust accordingly for java. using System; using System.Security.Cryptography; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.X509; using Org.BouncyCastle.Security; using Org.BouncyCastle.Crypto.Agreement; public static byte[] GetPublicKeyDerEncoded(AsymmetricCipherKeyPair AsymmetricKey) { return SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(AsymmetricKey.Public).GetDerEncoded(); } public static byte[] GetSharedSecret(AsymmetricCipherKeyPair localKeyWithPrivate, byte[] remotePublicKeyDerEncoded) { var remotePublicKey = PublicKeyFactory.CreateKey(remotePublicKeyDerEncoded); var agreement = new ECDHBasicAgreement(); agreement.Init(localKeyWithPrivate.Private); using (var sha = SHA256.Create()) { // CalculateAgreement returns a BigInteger, whose length is variable, and bits are not whitened. // So hash it. return sha.ComputeHash(agreement.CalculateAgreement(remotePublicKey).ToByteArray()); } } From: ziggi slaw [mailto:[hidden email]]
I have to implement a protocol where the client sends his EC public key and my fist step is to generate my own ephemeral EC public/private key pair and then calculate shared secret, which will be used later
to generate session keys. The elliptic curve in question is brainpoolP224r1. Below is my code (with hardcoded values), which either returs wrong result or throws an expection 'The multiplicator cannot be negative'. Any help would be
very appreciated. Thanks! |
In reply to this post by ziggi slaw
I think the issue is that it is interpreting the byte arrays as signed numbers, whereas the hex strings are actually for unsigned BigInts. Try: new BigInteger(hexValue, 16); rather than: new BigInteger(Conversions.HexStringToByteArray(hexValue)); Regards, David On 17/03/17 19:53, ziggi slaw wrote: > I have to implement a protocol where the client sends his EC public > key and my fist step is to generate my own ephemeral EC public/private > key pair and then calculate shared secret, which will be used later to > generate session keys. > > The elliptic curve in question is brainpoolP224r1. Below is my code > (with hardcoded values), which either returs wrong result or throws an > expection 'The multiplicator cannot be negative'. Any help would be > very appreciated. > > public static byte[] CalculateSharedSecret() > { > // Public key from the client. > var iccPublicKey = > "1A4C233D49F62BF7F419EBE6E2B81E936E88A93599BFDDE9205DA4DF984969C62695FD825A73F0207AB2D0CF9D5EF0DAAEA92360628032A0"; > > // My ephemeral EC key pair. > var privateKey = > "5744E0ED24B7C374DA05F6EBDD3BFDE0F0E629BF93294279B5F169BD"; > var publicKey = > "32924227C99ACAA858343C658D08C023316BFB87FE88E22D1F3A7E8D43ADCA39EBEF36904D64BAC677F11ECBEE501C9017808D4FA1AB8988"; > > // This is the expected result, but my function returns > 32FF74B40D904AE021BCB32B43B56C2D1E09752A47BE089CCED33197. > var expectedShareSecret = > "6CBE1E0F401F55B2479D44921068DCB19445E8A808ACEAE9B8E73505"; > > // Curve and curve parameters. > var curveParameters = > TeleTrusTNamedCurves.GetByName("brainpoolp224r1"); > var curve = curveParameters.Curve; > var curveIdentifier = TeleTrusTObjectIdentifiers.BrainpoolP224R1; > > // Calculate shared secret. > var iccPublicKeyLengthInBytes = iccPublicKey.Length / 2; > var iccPublicKeyX = iccPublicKey.Substring(0, > iccPublicKeyLengthInBytes); > var iccPublicKeyY = iccPublicKey.Substring(iccPublicKeyLengthInBytes); > var iccPublicKeyPoint = new ECPublicKeyParameters( > "ECDH", > new FpPoint( > curve, > new FpFieldElement(((FpCurve)curve).Q, new > BigInteger(Conversions.HexStringToByteArray(iccPublicKeyX))), > new FpFieldElement(((FpCurve)curve).Q, new > BigInteger(Conversions.HexStringToByteArray(iccPublicKeyY))) > ), > curveIdentifier > ); > var spec = new ECDomainParameters(curve, curveParameters.G, > curveParameters.N, curveParameters.H); > var keyParameters = new ECPrivateKeyParameters(new > BigInteger(Conversions.HexStringToByteArray(privateKey)), spec); > var agreement = new ECDHBasicAgreement(); > agreement.Init(keyParameters); > return agreement.CalculateAgreement(iccPublicKeyPoint).ToByteArray(); > } > > Thanks! |
Yes, I think that's it! This was a nasty bug to find, thanks! On Fri, Mar 17, 2017 at 9:46 PM, David Hook <[hidden email]> wrote:
|
Free forum by Nabble | Edit this page |