Вот соответствующий код:
Сначала я получаю сертификат X.509 и открытый ключ из YubiKey:
Код: Выделить всё
public X509Certificate getX509Certificate() throws CardException, IOException {
PIVPublicKeyParser parser = null;
X509Certificate x509Certificate = null;
if (isConnected && isAuthenticated && isSessionValid()) {
// Request certificate from YubiKey
CommandAPDU getCert = new CommandAPDU(pubKeyRequest);
response = channel.transmit(getCert);
// Parse certificate and extract public key
parser = new PIVPublicKeyParser(response.getData(), logger);
byte[] x509certBytes = parser.getCertBytes();
if (x509certBytes != null) {
x509Certificate = parser.getCertificate();
setPublicKey(parser.getPublicKey());
}
}
return x509Certificate;
}
Код: Выделить всё
public byte[] encryptKeyWithYubiKey(String key) {
try {
PublicKey publicKey = yubiKey.getPublicKey();
if (publicKey == null) {
throw new SecurityException("YubiKey public key not found");
}
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(key.getBytes());
} catch (Exception e) {
logger.error("Failed to encrypt key with stored public key", e);
throw new SecurityException("Failed to encrypt key with stored public key", e);
}
}
Код: Выделить всё
private static byte[] encodeData(byte[] dataToDecrypt, Logger logger) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Write 7C tag
baos.write(0x7C);
// Write length of entire structure
baos.write((byte)dataToDecrypt.length);
// Write fixed 82 00 tag
baos.write(0x82);
baos.write(0x00);
// Write 81 tag and data length
baos.write(0x81);
baos.write((byte)dataToDecrypt.length);
// Write encrypted data
baos.write(dataToDecrypt);
return baos.toByteArray();
}
public String decrypt(byte[] encryptedBytes) throws CardException {
try {
byte[] formattedData = encodeData(encryptedBytes, logger);
commandAPDU = new CommandAPDU(
0x00, // CLA
0x87, // INS - GENERAL AUTHENTICATE
0x07, // P1 - Algorithm (RSA-2048)
0x9A, // P2 - Key reference (PIV Authentication key)
formattedData // Data
);
response = channel.transmit(commandAPDU);
if (response.getSW() == 0x9000) {
byte[] responseData = response.getData();
byte[] decrypted = extractDataFromResponse(responseData);
return new String(decrypted).trim();
}
// Error 0x6A80 occurs here
logger.error("Decryption failed with status: {}", String.format("0x%04X", response.getSW()));
return null;
} catch (Exception e) {
logger.error("Decryption failed: {}", e.getMessage());
return null;
}
}
YubiKey аутентифицирован и сеанс действителен.
Зашифрованные данные имеют размер ровно 256 байт (RSA-2048).
Структура команд APDU следующая. документацию (за исключением того, что я, вероятно, использую неправильную длину в apdu.
Чего мне не хватает в форматировании данных для команды дешифрования?
Подробнее здесь: https://stackoverflow.com/questions/793 ... 6a80-error
Мобильная версия