3
votes

I have a custom crypto engine for Elliptic curve, I am trying to make this compatible with Java's bouncy castle crypto, so I am testing my API (keypair generation) against Java's bouncycastle.

First thing is to share the publickey between Java & my crypto engine that way I can get the same shared secret.

My module takes Elliptic curve 32-byte X & 32-byte Y values. I was able to output X & Y from Java code by calling "publickeyJava .toString()" below and output comes formated as 'X: .... and Y: ....." (as shown below). I copy pasted these X & Y values to my custom crypto engine and verified that I was able to get the same secret as generated by Java's bouncy castle, so I know my conversion works manually.

THE PROBLEM IS HOW TO EXTRACT THESE 32-BYTE X & Y VALUES IN JAVA PROGRAMATICALLY? I used java classes to get X & Y coordinate and printed with "getW.getAffineX() and getW.AffineY()" (as shown in my code below) but the values don't seem to match the output generated from "publickey.tostring" (which is what my module needs).

Is there a way to extract X & Y values from print "pubclickey.tostring"? Please suggest.

/*** Java code that prints Elliptic curve X & Y from bouncycastle crypto ****/

public static int generateECKeys() {
    try {
        ECNamedCurveParameterSpec parameterSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDH", "SC");

        keyPairGenerator.initialize(parameterSpec);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PublicKey publickeyJava = keyPair.getPublic();

        Log.e(TAG_LOG, "X & Y values are ...." + publickeyJava .toString());

        Log.d("LOG_TAG", "BigInteger X value is = " + ((ECPublicKey) publickeyJava).getW().getAffineX().toString());
        Log.d("LOG_TAG", "BigInteger Y value is = " + ((ECPublicKey) publickeyJava).getW().getAffineY().toString());
         /* .....code to generate shared secret   ..... */
        return 1;
    } catch(Exception e){e.printStackTrace();}
        return 0;
}

/******** OUTPUT ********/

X & Y values are ....EC Public Key             
    X: f98c87d3b6db30895b275630f30df9d796d067b06e4836f5615cad84965f4f85 
    Y: b8b58cb767f23e4bc4db0cc371ffb50cf12aa30407c1ba236f78a6c38948c2ee

BigInteger X value is = 324637435756455760457435640555474465574856445654455076545679
BigInteger Y value is = 954378375783465749076758439759347657056597437786534984623864

Thanks

2
The last two lines are obviously wrong because those numbers are too small. I tried your code using bouncycastle 1.52 on a desktop and got the correct answer. I can't explain your output.President James K. Polk
The first set of numbers is in hexadecimal form, while the numbers you print are in decimal. Try printing the numbers in base 16 (hexadecimal) and they should match.Iamsomeone
@Iamsomeone: Obviously they don't match. The hex values are 256 bits and the decimal values are much smaller.President James K. Polk
I solved the problem. I parsed the string containing X & Y and converted to a byte array to be usable in my CE.user3788234

2 Answers

0
votes

Today I got your same problem. I solved it in this way that it seems to me easier than parsing a String.

ECPublicKey publickeyJava = (ECPublicKey)keyPair.getPublic();
ECPoint ecp = chiavePubblica.getW();
// to access X and Y you can use
ecp.getAffineX()
ecp.getAffineY()
0
votes

Try toString(int radix) with radix of 16, as given below to get same X and Y values

Log.d("LOG_TAG", "BigInteger X value is = " + ((ECPublicKey) publickeyJava).getW().getAffineX().**toString(16)**); Log.d("LOG_TAG", "BigInteger Y value is = " + ((ECPublicKey) publickeyJava).getW().getAffineY().**toString(**16**)**);