use of es.gob.jmulticard.apdu.connection.ApduConnectionException in project jmulticard by ctt-gob-es.
the class CardOS method connect.
/**
* Conecta con el lector del sistema que tenga una CardOS insertada.
* @param conn Conexión hacia la tarjeta.
* @throws IOException Cuando hay errores de entrada / salida.
*/
private void connect(final ApduConnection conn) throws IOException {
if (conn == null) {
// $NON-NLS-1$
throw new IllegalArgumentException("La conexion no puede ser nula");
}
// Siemens CardOS son T=1
conn.setProtocol(ApduConnectionProtocol.T1);
final long[] terminals = conn.getTerminals(false);
if (terminals.length < 1) {
throw new NoReadersFoundException();
}
byte[] responseAtr;
Atr actualAtr;
InvalidCardException invalidCardException = null;
CardNotPresentException cardNotPresentException = null;
ApduConnectionException apduConnectionException = null;
for (final long terminal : terminals) {
conn.setTerminal((int) terminal);
try {
responseAtr = conn.reset();
} catch (final CardNotPresentException e) {
cardNotPresentException = e;
continue;
} catch (final ApduConnectionException e) {
apduConnectionException = e;
continue;
}
actualAtr = new Atr(responseAtr, ATR_MASK);
if (!ATR.equals(actualAtr)) {
// La tarjeta encontrada no es una CardOS
invalidCardException = new InvalidCardException(getCardName(), ATR, responseAtr);
continue;
}
return;
}
if (invalidCardException != null) {
throw invalidCardException;
}
if (cardNotPresentException != null) {
throw cardNotPresentException;
}
if (apduConnectionException != null) {
throw apduConnectionException;
}
// $NON-NLS-1$
throw new ApduConnectionException("No se ha podido conectar con ningun lector de tarjetas");
}
use of es.gob.jmulticard.apdu.connection.ApduConnectionException in project jmulticard by ctt-gob-es.
the class Dnie method getIccCertEncoded.
/**
* {@inheritDoc}
*/
@Override
public byte[] getIccCertEncoded() throws IOException {
byte[] iccCertEncoded;
try {
selectMasterFile();
iccCertEncoded = selectFileByIdAndRead(CERT_ICC_FILE_ID);
} catch (final ApduConnectionException e) {
throw new IOException(// $NON-NLS-1$
"Error en el envio de APDU para la seleccion del certificado de componente de la tarjeta: " + e, // $NON-NLS-1$
e);
} catch (final Iso7816FourCardException e) {
// $NON-NLS-1$
throw new IOException("Error en la seleccion del certificado de componente de la tarjeta: " + e, e);
}
return iccCertEncoded;
}
use of es.gob.jmulticard.apdu.connection.ApduConnectionException in project jmulticard by ctt-gob-es.
the class Cwa14890OneV1Connection method internalAuthentication.
/**
* Lleva a cabo el proceso de autenticación interna de la tarjeta mediante el
* cual el controlador comprueba la tarjeta.
* @param randomIfd Array de 8 bytes aleatorios.
* @param iccPublicKey Clava pública del certificado de componente.
* @return Semilla de 32 [KICC_LENGTH] bits, generada por la tarjeta, para la derivación de
* claves del canal seguro.
* @throws SecureChannelException Cuando ocurre un error en el establecimiento de claves.
* @throws ApduConnectionException Cuando ocurre un error en la comunicación con la tarjeta.
* @throws IOException Cuando ocurre un error en el cifrado/descifrado de los mensajes.
*/
private byte[] internalAuthentication(final byte[] randomIfd, final RSAPublicKey iccPublicKey) throws SecureChannelException, ApduConnectionException, IOException {
// este certificado de Terminal
try {
this.card.setKeysToAuthentication(this.card.getChrCCvIfd(this.pubConsts), this.card.getRefIccPrivateKey(this.pubConsts));
} catch (final Exception e) {
throw new SecureChannelException(// $NON-NLS-1$
"Error durante el establecimiento de la clave " + // $NON-NLS-1$
"publica de Terminal y la privada de componente para su atenticacion", // $NON-NLS-1$
e);
}
// Iniciamos la autenticacion interna de la clave privada del certificado de componente
final byte[] sigMinCiphered = this.card.getInternalAuthenticateMessage(randomIfd, this.card.getChrCCvIfd(this.pubConsts));
// Esta respuesta de la tarjeta es un mensaje:
// - Cifrado con la clave privada de componente de la tarjeta
// - Al que se le ha aplicado la funcion SIGMIN
// - Y que se ha cifrado con la clave publica del Terminal
// Para obtener el mensaje original deberemos deshacer cada una de estas operaciones en
// sentido inverso.
// El resultado sera correcto si empieza por el byte 0x6a [ISO_9796_2_PADDING_START] (ISO 9796-2, DS scheme 1) y
// termina con el byte 0xbc [ISO_9796_2_PADDING_END] (ISO-9796-2, Option 1).
// -- Descifrado con la clave privada del Terminal
final byte[] sigMin = this.cryptoHelper.rsaDecrypt(sigMinCiphered, this.card.getIfdPrivateKey(this.privConsts));
// Este resultado es el resultado de la funcion SIGMIN que es minimo de SIG (los
// datos sobre los que se ejecuto la funcion) y N.ICC-SIG.
// Debemos averiguar cual de los dos es. Empezamos por comprobar si es SIG con lo que no
// habra que deshacer la funcion y podemos descifrar directamente con la clave publica del
// certificado de componente de la tarjeta.
final byte[] sig = sigMin;
byte[] desMsg = this.cryptoHelper.rsaEncrypt(sig, iccPublicKey);
// Comprobamos que empiece por 0x6a [ISO_9796_2_PADDING_START] y termine con 0xbc [ISO_9796_2_PADDING_END]
if (desMsg[0] != ISO_9796_2_PADDING_START || desMsg[desMsg.length - 1] != ISO_9796_2_PADDING_END) {
// Calculamos N.ICC-SIG
final byte[] sub = iccPublicKey.getModulus().subtract(new BigInteger(sigMin)).toByteArray();
final byte[] niccMinusSig = new byte[this.card.getIfdKeyLength(this.pubConsts)];
// Ignoramos los ceros de la izquierda
if (sub.length > this.card.getIfdKeyLength(this.pubConsts) && sub[0] == (byte) 0x00) {
System.arraycopy(sub, 1, niccMinusSig, 0, sub.length - 1);
} else {
System.arraycopy(sub, 0, niccMinusSig, 0, sub.length);
}
// Desciframos el mensaje con N.ICC-SIG
desMsg = this.cryptoHelper.rsaDecrypt(niccMinusSig, iccPublicKey);
// la autenticacion interna habra fallado
if (desMsg[0] != ISO_9796_2_PADDING_START || desMsg[desMsg.length - 1] != ISO_9796_2_PADDING_END) {
throw new SecureChannelException(// $NON-NLS-1$
"Error en la autenticacion interna para el establecimiento del canal seguro. " + "El mensaje descifrado es:\n" + // $NON-NLS-1$
HexUtils.hexify(desMsg, true));
}
}
// -- Descomponemos el resultado anterior en sus partes:
// Byte 0: Relleno segun ISO 9796-2 (DS scheme 1)
// Bytes [PRND1] Bytes de relleno aleatorios para completar la longitud de la clave RSA
// Bytes [Kicc] Semilla de 32 [KICC_LENGTH] bytes generada por la tarjeta para la derivacion de claves
// Bytes [h: PRND1||Kicc||RND.IFD||SN.IFD] Hash SHA1
// Ultimo Byte: Relleno segun ISO-9796-2 (option 1)
final byte[] prnd1 = new byte[this.card.getIfdKeyLength(this.pubConsts) - KICC_LENGTH - SHA1_LENGTH - 2];
System.arraycopy(desMsg, 1, prnd1, 0, prnd1.length);
final byte[] kicc = new byte[KICC_LENGTH];
System.arraycopy(desMsg, prnd1.length + 1, kicc, 0, kicc.length);
final byte[] hash = new byte[SHA1_LENGTH];
System.arraycopy(desMsg, prnd1.length + kicc.length + 1, hash, 0, hash.length);
// -- Calculamos el hash para la comprobacion de la autenticacion, si coincide con el hash
// extraido en el paso anterior, se confirma que se ha realizado correctamente
// El hash se calcula a partir de la concatenacion de:
// - PRND1: Extraido del paso anterior
// - Kicc: Extraido del paso anterior
// - RND.IFD: Numero aleatorio generado en pasos anteriores
// - SN.IFD: CHR del IFD
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(prnd1);
baos.write(kicc);
baos.write(randomIfd);
baos.write(this.card.getChrCCvIfd(this.pubConsts));
final byte[] calculatedHash = this.cryptoHelper.digest(CryptoHelper.DigestAlgorithm.SHA1, baos.toByteArray());
if (!HexUtils.arrayEquals(hash, calculatedHash)) {
throw new SecureChannelException(// $NON-NLS-1$
"Error en la comprobacion de la clave de autenticacion interna. Se obtuvo el hash '" + HexUtils.hexify(calculatedHash, false) + "' cuando se esperaba: '" + HexUtils.hexify(hash, false) + // $NON-NLS-1$ //$NON-NLS-2$
"'");
}
return kicc;
}
use of es.gob.jmulticard.apdu.connection.ApduConnectionException in project jmulticard by ctt-gob-es.
the class Cwa14890OneV1Connection method open.
/**
* Abre el canal seguro con la tarjeta. La conexión se reiniciará previamente
* a la apertura del canal.
*/
@Override
public void open() throws ApduConnectionException {
final ApduConnection conn = this.subConnection;
conn.open();
// Obtenemos el numero de serie de la tarjeta.
// IMPORTANTE: Esta operacion debe realizarse antes del inicio del proceso de autenticacion
final byte[] serial = getPaddedSerial();
try {
this.card.verifyCaIntermediateIcc();
this.card.verifyIcc();
} catch (final SecurityException e) {
conn.close();
throw new IllegalStateException(// $NON-NLS-1$
"Condicion de seguridad no satisfecha en la validacion de los certificados CWA-14890: " + e);
} catch (final CertificateException e) {
conn.close();
throw new IllegalStateException(// $NON-NLS-1$
"No se han podido tratar los certificados CWA-14890: " + e);
} catch (final IOException e) {
conn.close();
throw new IllegalStateException(// $NON-NLS-1$
"No se han podido validar los certificados CWA-14890: " + e);
}
// Clave publica del certificado de componente de la tarjeta. Necesario para autenticacion interna
// y externa
final RSAPublicKey iccPublicKey;
try {
iccPublicKey = (RSAPublicKey) this.cryptoHelper.generateCertificate(this.card.getIccCertEncoded()).getPublicKey();
} catch (final CertificateException e) {
conn.close();
throw new ApduConnectionException(// $NON-NLS-1$
"No se pudo obtener la clave publica del certificado de componente: " + e, // $NON-NLS-1$
e);
} catch (final IOException e) {
conn.close();
throw new ApduConnectionException(// $NON-NLS-1$
"No se pudo leer certificado de componente: " + e, // $NON-NLS-1$
e);
}
// ---------------
try {
this.card.verifyIfdCertificateChain(this.pubConsts);
} catch (final Exception e) {
conn.close();
throw new ApduConnectionException(// $NON-NLS-1$
"Error al verificar la cadena de certificados del controlador: " + e, // $NON-NLS-1$
e);
}
// --- STAGE 3 ---
// Autenticacion interna (El driver comprueba la tarjeta)
// ---------------
final byte[] randomIfd;
try {
randomIfd = this.cryptoHelper.generateRandomBytes(8);
} catch (final IOException e1) {
conn.close();
throw new SecureChannelException(// $NON-NLS-1$
"No se pudo generar el array de aleatorios: " + e1, // $NON-NLS-1$
e1);
}
final byte[] kicc;
try {
kicc = this.internalAuthentication(randomIfd, iccPublicKey);
} catch (final Exception e) {
conn.close();
throw new ApduConnectionException(// $NON-NLS-1$
"Error durante el proceso de autenticacion interna de la tarjeta: " + e, // $NON-NLS-1$
e);
}
// --- STAGE 4 ---
// Autenticacion externa (La tarjeta comprueba el driver)
// ---------------
final byte[] randomIcc = this.card.getChallenge();
final byte[] kifd;
try {
kifd = this.externalAuthentication(serial, randomIcc, iccPublicKey);
} catch (final Exception e) {
conn.close();
throw new ApduConnectionException(// $NON-NLS-1$
"Error durante el proceso de autenticacion externa de la tarjeta", // $NON-NLS-1$
e);
}
// --- STAGE 5 ---
// Esta fase no pertenece al procedimiento de apertura del canal seguro (ya esta
// establecido), sino a la obtencion de las claves necesarias para su control. Estas
// son:
// - Kenc: Clave TripleDES (TDES o DESEDE) para encriptar y desencriptar criptogramas.
// - Kmac: Clave TripleDES (TDES o DESEDE) para calcular y verificar checksums.
// - SSC: Contador de secuencia.
// ---------------
// Calculamos Kifdicc como el XOR de los valores Kifd y Kicc
final byte[] kidficc = HexUtils.xor(kicc, kifd);
try {
this.kenc = generateKenc(kidficc);
} catch (final IOException e) {
conn.close();
throw new ApduConnectionException(// $NON-NLS-1$
"Error al generar la clave Kenc para el tratamiento del canal seguro", // $NON-NLS-1$
e);
}
try {
this.kmac = generateKmac(kidficc);
} catch (final IOException e) {
conn.close();
throw new ApduConnectionException(// $NON-NLS-1$
"Error al generar la clave Kmac para el tratamiento del canal seguro", // $NON-NLS-1$
e);
}
this.ssc = generateSsc(randomIfd, randomIcc);
this.openState = true;
}
use of es.gob.jmulticard.apdu.connection.ApduConnectionException 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ón hacia la tarjeta inteligente.
* @param cryptoHelper Clase para la realización de operaciones criptográficas auxiliares.
* @return SecureMessaging Objeto para el envío de mensajes seguros a través de canal PACE.
* @throws ApduConnectionException Si hay problemas de conexió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()]);
}
Aggregations