@Override public ECPublicKey decodePublicKey(byte[] key) throws IOException { TypesReader tr = new TypesReader(key); String keyFormat = tr.readString(); if (!keyFormat.equals(getKeyFormat())) { throw new IOException("Invalid key format"); } /* We need to read the next block, but don't do anything with it: the curve name is part of the key format which we've already checked above */ /*String curveName = */tr.readString(); byte[] groupBytes = tr.readByteString(); if (tr.remain() != 0) { throw new IOException("Unexpected adding in ECDSA public key"); } ECParameterSpec params = getEcParameterSpec(); ECPoint group = decodePoint(groupBytes, params.getCurve()); if (null == group) { throw new IOException("Invalid ECDSA group"); } try { KeySpec keySpec = new ECPublicKeySpec(group, params); KeyFactory kf = KeyFactory.getInstance("EC"); return (ECPublicKey) kf.generatePublic(keySpec); } catch (GeneralSecurityException ex) { throw new IOException("Could not decode ECDSA key", ex); } }
@Override public byte[] encodePublicKey(ECPublicKey key) throws IOException { byte[] encodedPoint = encodePoint(key.getW(), key.getParams().getCurve()); TypesWriter tw = new TypesWriter(); tw.writeString(getKeyFormat()); tw.writeString(getCurveName()); tw.writeString(encodedPoint, 0, encodedPoint.length); return tw.getBytes(); }
private static byte[] encodePoint(ECPoint group, EllipticCurve curve) { int elementSize = (curve.getField().getFieldSize() + 7) / 8; byte[] encodedPoint = new byte[2 * elementSize + 1]; encodedPoint[0] = 0x04; byte[] affineX = removeLeadingZeroes(group.getAffineX().toByteArray()); System.arraycopy(affineX, 0, encodedPoint, 1 + elementSize - affineX.length, affineX.length); byte[] affineY = removeLeadingZeroes(group.getAffineY().toByteArray()); System.arraycopy(affineY, 0, encodedPoint, 1 + elementSize + elementSize - affineY.length, affineY.length); return encodedPoint; }
if (!signatureFormat.equals(getKeyFormat())) { throw new IOException("Unsupported signature format: " + signatureFormat); writeLength(totalLength - 2, os); writeLength(rLength, os); if (rLength != r.length) { os.write(ANS1_ZERO); writeLength(sLength, os); if (sLength != s.length) { os.write(ANS1_ZERO);
@Override public boolean supportsKey(PrivateKey originalKey) { if (!(originalKey instanceof ECPrivateKey)) { return false; } ECPrivateKey key = (ECPrivateKey) originalKey; return super.supportsKey(key) && key.getParams().getCurve().getField().getFieldSize() == getEcParameterSpec().getCurve().getField().getFieldSize(); }
@Override public byte[] encodeSignature(byte[] sig) throws IOException { SimpleDERReader reader = new SimpleDERReader(new SimpleDERReader(sig).readSequenceAsByteArray()); BigInteger r = reader.readInt(); BigInteger s = reader.readInt(); TypesWriter rAndSWriter = new TypesWriter(); rAndSWriter.writeMPInt(r); rAndSWriter.writeMPInt(s); byte[] encoded = rAndSWriter.getBytes(); TypesWriter typesWriter = new TypesWriter(); typesWriter.writeString(getKeyFormat()); typesWriter.writeString(encoded, 0, encoded.length); return typesWriter.getBytes(); }