public EllipticCurveJsonWebKey(ECPublicKey publicKey) { super(publicKey); ECParameterSpec spec = publicKey.getParams(); EllipticCurve curve = spec.getCurve(); curveName = EllipticCurves.getName(curve); }
private int getCoordinateByteLength() { ECParameterSpec spec = EllipticCurves.getSpec(getCurveName()); return (int) Math.ceil(spec.getCurve().getField().getFieldSize() / 8d); }
private void checkPointIsOnCurve(ECPublicKey ephemeralPublicKey, ECPrivateKey privateKey) throws JoseException { // to prevent 'Invalid Curve Attack': for NIST curves, check whether public key is on the private key's curve. // from https://www.cs.bris.ac.uk/Research/CryptographySecurity/RWC/2017/nguyen.quan.pdf // there appear to be similar checks in the JVM starting with 1.8.0_51 but // doing it here explicitly seems prudent // (y^2) mod p = (x^3 + ax + b) mod p // thanks to Antonio Sanso for guidance on how to do this check ECParameterSpec ecParameterSpec = privateKey.getParams(); EllipticCurve curve = ecParameterSpec.getCurve(); ECPoint point = ephemeralPublicKey.getW(); BigInteger x = point.getAffineX(); BigInteger y = point.getAffineY(); BigInteger a = curve.getA(); BigInteger b = curve.getB(); BigInteger p = ((ECFieldFp) curve.getField()).getP(); BigInteger leftSide = (y.pow(2)).mod(p); BigInteger rightSide = (x.pow(3).add(a.multiply(x)).add(b)).mod(p); boolean onCurve = leftSide.equals(rightSide); if (!onCurve) { throw new JoseException(HeaderParameterNames.EPHEMERAL_PUBLIC_KEY + " is invalid for " + EllipticCurves.getName(curve)); } }
public EllipticCurveJsonWebKey(Map<String, Object> params, String jcaProvider) throws JoseException { super(params, jcaProvider); curveName = getString(params, CURVE_MEMBER_NAME, true); ECParameterSpec curve = EllipticCurves.getSpec(curveName); BigInteger x = getBigIntFromBase64UrlEncodedParam(params, X_MEMBER_NAME, true); BigInteger y = getBigIntFromBase64UrlEncodedParam(params, Y_MEMBER_NAME, true); EcKeyUtil keyUtil = new EcKeyUtil(jcaProvider, null); key = keyUtil.publicKey(x, y, curve); checkForBareKeyCertMismatch(); if (params.containsKey(PRIVATE_KEY_MEMBER_NAME)) { BigInteger d = getBigIntFromBase64UrlEncodedParam(params, PRIVATE_KEY_MEMBER_NAME, false); privateKey = keyUtil.privateKey(d, curve); } removeFromOtherParams(CURVE_MEMBER_NAME, X_MEMBER_NAME, Y_MEMBER_NAME, PRIVATE_KEY_MEMBER_NAME); }
private void validateKeySpec(Key key) throws InvalidKeyException { // some keys are valid for EC operations with the provider // (like with Sun PKCS11 provider https://bitbucket.org/b_c/jose4j/issues/77 ) // but aren't actually an instance of ECKey so only check the spec when we can if (key instanceof ECKey) { ECKey ecKey = (ECKey) key; ECParameterSpec spec = ecKey.getParams(); EllipticCurve curve = spec.getCurve(); String name = EllipticCurves.getName(curve); if (!getCurveName().equals(name)) { throw new InvalidKeyException(getAlgorithmIdentifier() + "/" + getJavaAlgorithm() + " expects a key using " + getCurveName() + " but was " + name); } } }