Search code examples
javajavacardelliptic-curveecdsa

Generating ECDSA public key at host side from W parameter


I want to send the public key of the private-public key pair (ECDSA) generated in my applet to the host application/terminal.

In RSA normally i would send the modulus and exponent and will generate the public key at the host side.

In ECDSA i read from the link that we can do the same if you take the W parameter bytes outside the card Click here: Stackoverflow Answer: encode public key on Java

I have the W bytes from the card now. can someone suggest how to create the public key from this?


Solution

  • I wrote this method to convert an EC Public key into java.security.interfaces.ECPublicKey key object. To do this I use Bouncy Castle provider (bcprov-ext-jdk16-1.46.jar). You can download the latest version from here.

    /**
     * This method converts the EC public key (ECPublicKey#getW()) into ECPublicKey
     * @param cardPublicKey as W
     * @param curveName (for example "P-224")
     * @return java.security.interfaces.ECPublicKey
     */
    public ECPublicKey ucPublicKeyToPublicKey(byte[] cardPublicKey, String curveName) {
        //for example curveName = "P-224";
        java.security.interfaces.ECPublicKey ecPublicKey = null; // java.security.interfaces.ECPublicKey
        java.security.KeyFactory kf = null;
    
        org.bouncycastle.jce.spec.ECNamedCurveParameterSpec ecNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec(curveName);
        org.bouncycastle.math.ec.ECCurve curve = ecNamedCurveParameterSpec.getCurve();
        java.security.spec.EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, ecNamedCurveParameterSpec.getSeed());
        java.security.spec.ECPoint ecPoint = ECPointUtil.decodePoint(ellipticCurve, cardPublicKey);
        java.security.spec.ECParameterSpec ecParameterSpec = EC5Util.convertSpec(ellipticCurve, ecNamedCurveParameterSpec);
        java.security.spec.ECPublicKeySpec publicKeySpec = new java.security.spec.ECPublicKeySpec(ecPoint, ecParameterSpec);
    
        try {
            kf = java.security.KeyFactory.getInstance("EC", "BC");
        } catch (Exception e) {
            System.out.println("Caught Exception kf : " + e.toString());
        }
    
        try {
            ecPublicKey = (ECPublicKey) kf.generatePublic(publicKeySpec);
        } catch (Exception e) {
            System.out.println("Caught Exception public key: " + e.toString());
        }
    
        return ecPublicKey;
    }