use of es.gob.jmulticard.asn1.bertlv.BerTlv in project jmulticard by ctt-gob-es.
the class ApduEncrypterDes method decryptResponseApdu.
/**
* Desencripta los datos de una APDU de respuesta protegida.
* @param responseApdu APDU de respuesta cifrada.
* @param keyCipher Clave para el descifrado de la respuesta.
* @param ssc Código de secuencia correspondiente a la respuesta.
* @param kMac Clave para la verificación de la respuesta.
* @param cryptoHelper Manejador para el desencriptado.
* @return APDU con la respuesta descifrada.
* @throws IOException Cuando ocurre un error durante la desencriptación de los datos.
*/
@Override
public ResponseApdu decryptResponseApdu(final ResponseApdu responseApdu, final byte[] keyCipher, final byte[] ssc, final byte[] kMac, final CryptoHelper cryptoHelper) throws IOException {
// Si el resultado es incorrecto, lo devolvemos para su evaluacion
if (!responseApdu.isOk()) {
return new ResponseApdu(responseApdu.getStatusWord().getBytes());
}
// Desciframos y validamos el resultado
final ByteArrayInputStream recordOfTlvs = new ByteArrayInputStream(responseApdu.getData());
BerTlv dataTlv = null;
BerTlv swTlv = null;
BerTlv macTlv = null;
try {
BerTlv tlv = BerTlv.getInstance(recordOfTlvs);
if (tlv.getTag().getTagValue() == TAG_DATA_TLV) {
dataTlv = tlv;
tlv = BerTlv.getInstance(recordOfTlvs);
}
if (tlv.getTag().getTagValue() == TAG_SW_TLV) {
swTlv = tlv;
tlv = BerTlv.getInstance(recordOfTlvs);
}
if (tlv.getTag().getTagValue() == TAG_MAC_TLV) {
macTlv = tlv;
}
} catch (final NegativeArraySizeException e) {
// $NON-NLS-1$
throw new ApduConnectionException("Error en el formato de la respuesta remitida por el canal seguro", e);
}
if (macTlv == null) {
// $NON-NLS-1$
throw new SecureChannelException("No se ha encontrado el TLV del MAC en la APDU");
}
if (swTlv == null) {
// $NON-NLS-1$
throw new SecureChannelException("No se ha encontrado el TLV del StatusWord en la APDU cifrada");
}
// Pasamos el TLV completo de datos y el del StatusWord concatenados
final int tlvsLenght = // Tag (1 byte) + Lenght (1 byte + 1 por cada 128) + Value (Value.lenght bytes
(dataTlv != null ? 1 + 1 + dataTlv.getValue().length / 128 + dataTlv.getValue().length : 0) + 1 + 1 + // Tag (1 byte) + Lenght (1 byte) + Value (Value.lenght bytes)
swTlv.getValue().length;
verifyMac(HexUtils.subArray(responseApdu.getData(), 0, tlvsLenght), macTlv.getValue(), ssc, kMac, cryptoHelper);
if (dataTlv == null) {
return new ResponseApdu(swTlv.getValue());
}
// Desencriptamos y eliminamos el padding de los datos, teniendo en cuenta que el primer byte
// de los datos es fijo (0x01) y no cuenta dentro de los datos
final byte[] decryptedData = removePadding7816(cryptoHelper.desedeDecrypt(HexUtils.subArray(dataTlv.getValue(), 1, dataTlv.getValue().length - 1), keyCipher));
final byte[] responseApduBytes = new byte[decryptedData.length + swTlv.getValue().length];
System.arraycopy(decryptedData, 0, responseApduBytes, 0, decryptedData.length);
System.arraycopy(swTlv.getValue(), 0, responseApduBytes, decryptedData.length, swTlv.getValue().length);
return new ResponseApdu(responseApduBytes);
}
Aggregations