Search in sources :

Example 31 with X9ECParameters

use of org.bouncycastle.asn1.x9.X9ECParameters in project incubator-pulsar by apache.

the class MessageCrypto method loadPublicKey.

private PublicKey loadPublicKey(byte[] keyBytes) throws Exception {
    Reader keyReader = new StringReader(new String(keyBytes));
    PublicKey publicKey = null;
    try (org.bouncycastle.openssl.PEMParser pemReader = new org.bouncycastle.openssl.PEMParser(keyReader)) {
        Object pemObj = pemReader.readObject();
        JcaPEMKeyConverter pemConverter = new JcaPEMKeyConverter();
        SubjectPublicKeyInfo keyInfo = null;
        X9ECParameters ecParam = null;
        if (pemObj instanceof ASN1ObjectIdentifier) {
            // make sure this is EC Parameter we're handling. In which case
            // we'll store it and read the next object which should be our
            // EC Public Key
            ASN1ObjectIdentifier ecOID = (ASN1ObjectIdentifier) pemObj;
            ecParam = ECNamedCurveTable.getByOID(ecOID);
            if (ecParam == null) {
                throw new PEMException("Unable to find EC Parameter for the given curve oid: " + ((ASN1ObjectIdentifier) pemObj).getId());
            }
            pemObj = pemReader.readObject();
        } else if (pemObj instanceof X9ECParameters) {
            ecParam = (X9ECParameters) pemObj;
            pemObj = pemReader.readObject();
        }
        if (pemObj instanceof org.bouncycastle.cert.X509CertificateHolder) {
            keyInfo = ((org.bouncycastle.cert.X509CertificateHolder) pemObj).getSubjectPublicKeyInfo();
        } else {
            keyInfo = (SubjectPublicKeyInfo) pemObj;
        }
        publicKey = pemConverter.getPublicKey(keyInfo);
        if (ecParam != null && ECDSA.equals(publicKey.getAlgorithm())) {
            ECParameterSpec ecSpec = new ECParameterSpec(ecParam.getCurve(), ecParam.getG(), ecParam.getN(), ecParam.getH(), ecParam.getSeed());
            KeyFactory keyFactory = KeyFactory.getInstance(ECDSA, BouncyCastleProvider.PROVIDER_NAME);
            ECPublicKeySpec keySpec = new ECPublicKeySpec(((BCECPublicKey) publicKey).getQ(), ecSpec);
            publicKey = (PublicKey) keyFactory.generatePublic(keySpec);
        }
    } catch (IOException | NoSuchAlgorithmException | NoSuchProviderException | InvalidKeySpecException e) {
        throw new Exception(e);
    }
    return publicKey;
}
Also used : X9ECParameters(org.bouncycastle.asn1.x9.X9ECParameters) Reader(java.io.Reader) CryptoKeyReader(org.apache.pulsar.client.api.CryptoKeyReader) StringReader(java.io.StringReader) JcaPEMKeyConverter(org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter) ByteString(com.google.protobuf.ByteString) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) SubjectPublicKeyInfo(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo) ECPublicKeySpec(org.bouncycastle.jce.spec.ECPublicKeySpec) PEMParser(org.bouncycastle.openssl.PEMParser) StringReader(java.io.StringReader) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) KeyFactory(java.security.KeyFactory) BCECPublicKey(org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey) PublicKey(java.security.PublicKey) PEMParser(org.bouncycastle.openssl.PEMParser) IOException(java.io.IOException) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ShortBufferException(javax.crypto.ShortBufferException) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) CryptoException(org.apache.pulsar.client.api.PulsarClientException.CryptoException) PEMException(org.bouncycastle.openssl.PEMException) IOException(java.io.IOException) BadPaddingException(javax.crypto.BadPaddingException) NoSuchProviderException(java.security.NoSuchProviderException) ECParameterSpec(org.bouncycastle.jce.spec.ECParameterSpec) PEMException(org.bouncycastle.openssl.PEMException) NoSuchProviderException(java.security.NoSuchProviderException) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Example 32 with X9ECParameters

use of org.bouncycastle.asn1.x9.X9ECParameters in project jmulticard by ctt-gob-es.

the class PaceChannelHelper method openPaceChannel.

/**
 * Abre un canal PACE.
 * @param cla Clase de APDU para los comandos de establecimiento de canal.
 * @param pi Valor de inicialización del canal. Puede ser un CAN
 *           (<i>Card Access Number</i>) o una MRZ (<i>Machine Readable Zone</i>).
 * @param conn Conexi&oacute;n hacia la tarjeta inteligente.
 * @param cryptoHelper Clase para la realizaci&oacute;n de operaciones criptogr&aacute;ficas auxiliares.
 * @return SecureMessaging Objeto para el env&iacute;o de mensajes seguros a trav&eacute;s de canal PACE.
 * @throws ApduConnectionException Si hay problemas de conexi&oacute;n con la tarjeta.
 * @throws PaceException Si hay problemas en la apertura del canal.
 */
public static SecureMessaging openPaceChannel(final byte cla, final PaceInitializer pi, final ApduConnection conn, final CryptoHelper cryptoHelper) throws ApduConnectionException, PaceException {
    if (conn == null) {
        throw new IllegalArgumentException(// $NON-NLS-1$
        "El canal de conexion no puede ser nulo");
    }
    if (pi == null) {
        throw new IllegalArgumentException(// $NON-NLS-1$
        "Es necesario proporcionar un inicializador para abrir canal PACE");
    }
    if (cryptoHelper == null) {
        throw new IllegalArgumentException(// $NON-NLS-1$
        "El CryptoHelper no puede ser nulo");
    }
    if (!conn.isOpen()) {
        conn.open();
    }
    ResponseApdu res;
    CommandApdu comm;
    // 1.3.2 - Establecemos el algoritmo para PACE con el comando MSE Set:
    comm = new MseSetPaceAlgorithmApduCommand(cla, MseSetPaceAlgorithmApduCommand.PaceAlgorithmOid.PACE_ECDH_GM_AES_CBC_CMAC128, pi.getPasswordType(), MseSetPaceAlgorithmApduCommand.PaceAlgorithmParam.BRAINPOOL_256_R1);
    res = conn.transmit(comm);
    if (!res.isOk()) {
        throw new PaceException(res.getStatusWord(), comm, // $NON-NLS-1$
        "Error estableciendo el algoritmo del protocolo PACE.");
    }
    // 1.3.3 - Primer comando General Autenticate - Get Nonce
    comm = new GeneralAuthenticateApduCommand((byte) 0x10, new byte[] { (byte) 0x7C, (byte) 0x00 });
    res = conn.transmit(comm);
    if (!res.isOk()) {
        throw new PaceException(res.getStatusWord(), comm, // $NON-NLS-1$
        "Error solicitando el aleatorio de calculo PACE (Nonce)");
    }
    // Calcular nonce devuelto por la tarjeta que se empleara en los calculos
    final byte[] nonce;
    try {
        nonce = new Tlv(new Tlv(res.getData()).getValue()).getValue();
    } catch (final TlvException e) {
        throw new PaceException(// $NON-NLS-1$ //$NON-NLS-2$
        "El aleatorio de calculo PACE (Nonce) obtenido (" + HexUtils.hexify(res.getData(), true) + ") no sigue el formato esperado: " + e, // $NON-NLS-1$ //$NON-NLS-2$
        e);
    }
    // Calcular sk = SHA-1( CAN || 00000003 );
    // La clave son los 16 bytes MSB del hash
    final byte[] sk = new byte[16];
    try {
        System.arraycopy(cryptoHelper.digest(CryptoHelper.DigestAlgorithm.SHA1, HexUtils.concatenateByteArrays(pi.getBytes(), CAN_MRZ_PADDING)), 0, sk, 0, 16);
    } catch (final IOException e) {
        throw new PaceException(// $NON-NLS-1$
        "Error obteniendo el 'sk' a partir del CAN: " + e, // $NON-NLS-1$
        e);
    }
    // Calcular secret = AES_Dec(nonce,sk);
    final byte[] secret_nonce;
    try {
        secret_nonce = cryptoHelper.aesDecrypt(nonce, new byte[0], sk);
    } catch (final Exception e) {
        throw new PaceException(// $NON-NLS-1$
        "Error descifranco el 'nonce': " + e, // $NON-NLS-1$
        e);
    }
    // 1.3.4 - Segundo comando General Autenticate - Map Nonce
    // Generamos un par de claves efimeras EC para el DH
    // $NON-NLS-1$
    final X9ECParameters ecdhParameters = TeleTrusTNamedCurves.getByName("brainpoolp256r1");
    final ECPoint pointG = ecdhParameters.getG();
    final Fp curve = (org.spongycastle.math.ec.ECCurve.Fp) ecdhParameters.getCurve();
    // La privada del terminal se genera aleatoriamente (PrkIFDDH1)
    // La publica de la tarjeta sera devuelta por ella misma al enviar nuesra publica (pukIFDDH1)
    final Random rnd = new Random();
    rnd.setSeed(rnd.nextLong());
    final byte[] x1 = new byte[curve.getFieldSize() / 8];
    rnd.nextBytes(x1);
    final BigInteger PrkIFDDH1 = new BigInteger(1, x1);
    // Enviamos nuestra clave publica (pukIFDDH1 = G*PrkIFDDH1)
    final ECPoint pukIFDDH1 = pointG.multiply(PrkIFDDH1);
    Tlv tlv = new Tlv(TAG_DYNAMIC_AUTHENTICATION_DATA, new Tlv(TAG_GEN_AUTH_2, pukIFDDH1.getEncoded(false)).getBytes());
    // ... Y la enviamos a la tarjeta
    comm = new GeneralAuthenticateApduCommand((byte) 0x10, tlv.getBytes());
    res = conn.transmit(comm);
    if (!res.isOk()) {
        throw new PaceException(res.getStatusWord(), comm, // $NON-NLS-1$
        "Error mapeando el aleatorio de calculo PACE (Nonce)");
    }
    // Se obtiene la clave publica de la tarjeta
    final byte[] pukIccDh1;
    try {
        pukIccDh1 = unwrapEcKey(res.getData());
    } catch (final Exception e) {
        throw new PaceException(// $NON-NLS-1$
        "Error obteniendo la clave efimera EC publica de la tarjeta: " + e, // $NON-NLS-1$
        e);
    }
    // calcular blinding point H = PrkIFDDH1 * PukICCDH1
    final ECPoint y1FromG = byteArrayToECPoint(pukIccDh1, curve);
    // Calculamos el punto H secreto
    final ECPoint SharedSecret_H = y1FromG.multiply(PrkIFDDH1);
    // Se calcula el nuevo punto G' = nonce*G + H
    final BigInteger ms = new BigInteger(1, secret_nonce);
    final ECPoint g_temp = pointG.multiply(ms);
    final ECPoint newPointG = g_temp.add(SharedSecret_H);
    // 1.3.5 Tercer comando General Authenticate
    // Se calcula la coordenada X de G' y generamos con la tarjeta un nuevo acuerdo de claves
    // La privada del terminal se genera aleatoriamente (PrkIFDDH2)
    // La publica de la tarjeta sera devuelta por ella misma al enviar nuesra publica (pukIFDDH2)
    final byte[] x2 = new byte[curve.getFieldSize() / 8];
    rnd.setSeed(rnd.nextLong());
    rnd.nextBytes(x2);
    final BigInteger PrkIFDDH2 = new BigInteger(1, x2);
    // Enviamos nuestra clave publica (pukIFDDH2 = G'*PrkIFDDH2)
    final ECPoint pukIFDDH2 = newPointG.multiply(PrkIFDDH2);
    // ... La metemos en un TLV de autenticacion ...
    tlv = new Tlv(TAG_DYNAMIC_AUTHENTICATION_DATA, new Tlv(TAG_GEN_AUTH_3, pukIFDDH2.getEncoded(false)).getBytes());
    comm = new GeneralAuthenticateApduCommand((byte) 0x10, tlv.getBytes());
    res = conn.transmit(comm);
    // Se obtiene la clave publica de la tarjeta (pukIccDh2) que es la coordenada Y del nuevo Punto G'
    final byte[] pukIccDh2;
    try {
        pukIccDh2 = unwrapEcKey(res.getData());
    } catch (final Exception e) {
        throw new PaceException(// $NON-NLS-1$
        "Error obteniendo la clave efimera EC publica de la tarjeta: " + e, // $NON-NLS-1$
        e);
    }
    final ECPoint y2FromNewG = byteArrayToECPoint(pukIccDh2, curve);
    // Se calcula el secreto k = PukICCDH2 * PrkIFDDH2
    final ECPoint.Fp SharedSecret_K = (org.spongycastle.math.ec.ECPoint.Fp) y2FromNewG.multiply(PrkIFDDH2);
    final byte[] secretK = bigIntToByteArray(SharedSecret_K.normalize().getXCoord().toBigInteger());
    // 1.3.6 Cuarto comando General Authenticate
    // Se validan las claves de sesion generadas en el paso anterior,
    // por medio de un MAC que calcula el terminal y comprueba la tarjeta,
    // la cual devolvera un segundo MAC.
    // Calcular kenc = SHA-1( k || 00000001 );
    final byte[] kenc = new byte[16];
    try {
        System.arraycopy(cryptoHelper.digest(CryptoHelper.DigestAlgorithm.SHA1, HexUtils.concatenateByteArrays(secretK, KENC_PADDING)), 0, kenc, 0, 16);
    } catch (final IOException e) {
        throw new PaceException(// $NON-NLS-1$
        "Error obteniendo el 'kenc' a partir del CAN: " + e, // $NON-NLS-1$
        e);
    }
    // Calcular kmac = SHA-1( k || 00000002 );
    final byte[] kmac = new byte[16];
    try {
        System.arraycopy(cryptoHelper.digest(CryptoHelper.DigestAlgorithm.SHA1, HexUtils.concatenateByteArrays(secretK, KMAC_PADDING)), 0, kmac, 0, 16);
    } catch (final IOException e) {
        throw new PaceException(// $NON-NLS-1$
        "Error obteniendo el 'kmac' a partir del CAN: " + e, // $NON-NLS-1$
        e);
    }
    // Elimina el byte '04' del inicio que es el indicador de punto descomprimido
    final byte[] pukIccDh2Descompressed = new byte[pukIccDh2.length - 1];
    System.arraycopy(pukIccDh2, 1, pukIccDh2Descompressed, 0, pukIccDh2.length - 1);
    // Se calcula el Mac del terminal: data = '7f494F06' + oid + '864104' + PukICCDH2;
    final byte[] data = HexUtils.concatenateByteArrays(MAC_PADDING, HexUtils.concatenateByteArrays(MseSetPaceAlgorithmApduCommand.PaceAlgorithmOid.PACE_ECDH_GM_AES_CBC_CMAC128.getBytes(), HexUtils.concatenateByteArrays(MAC2_PADDING, pukIccDh2Descompressed)));
    byte[] mac8bytes;
    try {
        mac8bytes = cryptoHelper.doAesCmac(data, kmac);
    } catch (final Exception e) {
        throw new PaceException(// $NON-NLS-1$
        "Error descifrando el 'nonce': " + e, // $NON-NLS-1$
        e);
    }
    // ... La metemos en un TLV de autenticacion ...
    tlv = new Tlv(TAG_DYNAMIC_AUTHENTICATION_DATA, new Tlv(TAG_GEN_AUTH_4, mac8bytes).getBytes());
    // Se envia el comando General Authenticate y se recupera el MAC devuelto por la tarjeta.
    comm = new GeneralAuthenticateApduCommand((byte) 0x00, tlv.getBytes());
    res = conn.transmit(comm);
    // Se obtiene un MAC con respuesta 90-00 indicando que se ha establecido el canal correctamente
    if (!res.isOk()) {
        throw new PaceException(res.getStatusWord(), comm, // $NON-NLS-1$
        "Error estableciendo el algoritmo del protocolo PACE.");
    }
    // Se inicializa el contador de secuencia a ceros
    final byte[] ssc = new byte[16];
    Arrays.fill(ssc, (byte) 0);
    // $NON-NLS-1$
    LOGGER.info("Canal Pace abierto");
    LOGGER.info(// $NON-NLS-1$
    "\nKenc: " + HexUtils.hexify(kenc, true) + "Kmac: " + // $NON-NLS-1$
    HexUtils.hexify(kmac, true) + "Ssc: " + // $NON-NLS-1$
    HexUtils.hexify(ssc, true));
    final AmCryptoProvider crypto = new AmAESCrypto();
    return new SecureMessaging(crypto, kenc, kmac, new byte[crypto.getBlockSize()]);
}
Also used : CommandApdu(es.gob.jmulticard.apdu.CommandApdu) SecureMessaging(es.gob.jmulticard.de.tsenger.androsmex.iso7816.SecureMessaging) AmAESCrypto(es.gob.jmulticard.de.tsenger.androsmex.crypto.AmAESCrypto) X9ECParameters(org.spongycastle.asn1.x9.X9ECParameters) ResponseApdu(es.gob.jmulticard.apdu.ResponseApdu) Fp(org.spongycastle.math.ec.ECCurve.Fp) IOException(java.io.IOException) ECPoint(org.spongycastle.math.ec.ECPoint) ApduConnectionException(es.gob.jmulticard.apdu.connection.ApduConnectionException) IOException(java.io.IOException) TlvException(es.gob.jmulticard.asn1.TlvException) AmCryptoProvider(es.gob.jmulticard.de.tsenger.androsmex.crypto.AmCryptoProvider) TlvException(es.gob.jmulticard.asn1.TlvException) Random(java.util.Random) MseSetPaceAlgorithmApduCommand(es.gob.jmulticard.apdu.iso7816four.pace.MseSetPaceAlgorithmApduCommand) GeneralAuthenticateApduCommand(es.gob.jmulticard.apdu.iso7816four.GeneralAuthenticateApduCommand) BigInteger(java.math.BigInteger) Tlv(es.gob.jmulticard.asn1.Tlv)

Example 33 with X9ECParameters

use of org.bouncycastle.asn1.x9.X9ECParameters in project oxAuth by GluuFederation.

the class SHA256withECDSASignatureVerification method decodePublicKey.

@Override
public PublicKey decodePublicKey(byte[] encodedPublicKey) throws SignatureException {
    X9ECParameters curve = SECNamedCurves.getByName("secp256r1");
    ECPoint point = curve.getCurve().decodePoint(encodedPublicKey);
    try {
        return KeyFactory.getInstance("ECDSA").generatePublic(new ECPublicKeySpec(point, new ECParameterSpec(curve.getCurve(), curve.getG(), curve.getN(), curve.getH())));
    } catch (GeneralSecurityException ex) {
        throw new SignatureException(ex);
    }
}
Also used : X9ECParameters(org.bouncycastle.asn1.x9.X9ECParameters) ECParameterSpec(org.bouncycastle.jce.spec.ECParameterSpec) GeneralSecurityException(java.security.GeneralSecurityException) SignatureException(org.gluu.oxauth.model.exception.SignatureException) ECPoint(org.bouncycastle.math.ec.ECPoint) ECPublicKeySpec(org.bouncycastle.jce.spec.ECPublicKeySpec)

Example 34 with X9ECParameters

use of org.bouncycastle.asn1.x9.X9ECParameters in project open-ecard by ecsec.

the class ExplicitDomainParameters method loadECDHParameter.

private void loadECDHParameter(ASN1Sequence seq) {
    // ASN1Integer version = (ASN1Integer) seq.getObjectAt(0);
    // ASN1Sequence modulus = (ASN1Sequence) seq.getObjectAt(1);
    // ASN1Sequence coefficient = (ASN1Sequence) seq.getObjectAt(2);
    // ASN1OctetString basepoint = (ASN1OctetString) seq.getObjectAt(3);
    ASN1Integer order = (ASN1Integer) seq.getObjectAt(4);
    ASN1Integer cofactor = (ASN1Integer) seq.getObjectAt(5);
    try {
        // BigInteger p = new BigInteger(modulus.getObjectAt(1).toASN1Primitive().getEncoded());
        // BigInteger a = new BigInteger(coefficient.getObjectAt(0).toASN1Primitive().getEncoded());
        // BigInteger b = new BigInteger(coefficient.getObjectAt(1).toASN1Primitive().getEncoded());
        BigInteger r = order.getValue();
        BigInteger f = cofactor.getValue();
        X9ECParameters ECParameters = X9ECParameters.getInstance(seq);
        ECCurve curve = ECParameters.getCurve();
        domainParameter = new ECParameterSpec(curve, ECParameters.getG(), r, f);
    } catch (Exception e) {
        _logger.error("Failed to load proprietary domain parameters", e);
    }
}
Also used : X9ECParameters(org.openecard.bouncycastle.asn1.x9.X9ECParameters) ECParameterSpec(org.openecard.bouncycastle.jce.spec.ECParameterSpec) ECCurve(org.openecard.bouncycastle.math.ec.ECCurve) BigInteger(java.math.BigInteger) ASN1Integer(org.openecard.bouncycastle.asn1.ASN1Integer)

Example 35 with X9ECParameters

use of org.bouncycastle.asn1.x9.X9ECParameters in project OsmAnd-tools by osmandapp.

the class SigningUtils method derivePublicKey.

/**
 * Step (8) to (11): Derive pubkey from passphrase
 * @param privBytes
 * @return
 * @throws BlockIOException
 */
static byte[] derivePublicKey(byte[] privBytes) throws BlockIOException {
    X9ECParameters params = SECNamedCurves.getByName("secp256k1");
    ECDomainParameters ecParams = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
    BigInteger priv = new BigInteger(1, privBytes);
    byte[] pubBytes = ecParams.getG().multiply(priv).getEncoded(true);
    return pubBytes;
}
Also used : ECDomainParameters(org.bouncycastle.crypto.params.ECDomainParameters) X9ECParameters(org.bouncycastle.asn1.x9.X9ECParameters) BigInteger(java.math.BigInteger)

Aggregations

X9ECParameters (org.bouncycastle.asn1.x9.X9ECParameters)33 X962Parameters (org.bouncycastle.asn1.x9.X962Parameters)16 ECNamedCurveSpec (org.bouncycastle.jce.spec.ECNamedCurveSpec)13 IOException (java.io.IOException)12 ECCurve (org.bouncycastle.math.ec.ECCurve)12 BigInteger (java.math.BigInteger)10 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)10 AlgorithmIdentifier (org.bouncycastle.asn1.x509.AlgorithmIdentifier)10 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)8 DERObjectIdentifier (org.bouncycastle.asn1.DERObjectIdentifier)8 X9ECPoint (org.bouncycastle.asn1.x9.X9ECPoint)8 ECPoint (java.security.spec.ECPoint)7 ASN1Encodable (org.bouncycastle.asn1.ASN1Encodable)7 ECDomainParameters (org.bouncycastle.crypto.params.ECDomainParameters)7 ECParameterSpec (java.security.spec.ECParameterSpec)6 EllipticCurve (java.security.spec.EllipticCurve)6 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)6 ECParameterSpec (org.bouncycastle.jce.spec.ECParameterSpec)6 DERInteger (org.bouncycastle.asn1.DERInteger)5 PrivateKeyInfo (org.bouncycastle.asn1.pkcs.PrivateKeyInfo)5