Статус: Активный участник
Группы: Участники
Зарегистрирован: 29.03.2011(UTC) Сообщений: 163 Откуда: Москва Сказал «Спасибо»: 8 раз Поблагодарили: 3 раз в 3 постах
|
Итак. Получен кусок неработающего кода. Приведу его как есть на Java, чтобы не ошибиться при транслировании на Си. Он в принципе понятен. Шифрование проходит без проблем: Код:
public static CryptData cryptData(PCCERT_CONTEXT cert, byte[] data) throws CryptoException {
final KeyContext userKey = SignUtils.getUserKey(cert);
if (userKey == null)
throw new CryptoException("User key not found");
final Pointer sessKey = Advapi.cryptGenKey(userKey.getProvHandle(), Wincrypt.CALG_G28147, Wincrypt.CRYPT_EXPORTABLE);
try {
final byte[] ecnryptedData = Advapi.cryptEncrypt(sessKey, null, true, data);
final byte[] iv = new byte[8];
final byte[] sv = new byte[8];
final byte[] sessKeyData = exportSessionKey(userKey, sessKey, iv, sv);
return new CryptData(ecnryptedData, sessKeyData, iv, sv);
} finally {
userKey.free();
}
}
private static byte[] exportSessionKey(KeyContext userKey, Pointer sessionKey, /* out */ byte[] iv, /* out */ byte[] sv) throws CryptoException {
final Pointer hProv = userKey.getProvHandle();
// получаем вектор инициализации
final byte[] ivData = cryptGetKeyParam(sessionKey, KP_IV);
// копируем вектор в out - переменную
System.arraycopy(ivData, 0, iv, 0, 8);
// генерируем ефемерную пару
final Pointer ephemKey = Advapi.cryptGenKey(hProv, CALG_DH_EL_EPHEM, CRYPT_EXPORTABLE);
// Генерируем в 2 шага ключ согласования agreeKey. Для этого импортируем наш публичный ключ, используя эфемерную пару.
// 1. Экспортируем наш публичный ключ
final byte[] pubKeyData = cryptExportKey(userKey.getKeyHandle(), null, PUBLICKEYBLOB, 0);
// 2. Импортируем при помощи эфемерной пары
final Pointer agreeKey = Advapi.cryptImportKey(hProv, pubKeyData, ephemKey, 0);
// получаем вектор инициализации
final byte[] svData = cryptGetKeyParam(agreeKey, KP_IV);
// копируем вектор в out - переменную
System.arraycopy(svData, 0, sv, 0, 8);
// Экспортируем симметричный ключ шифрования с использованием ключа согласования
final byte[] sessKeyData = cryptExportKey(sessionKey, agreeKey, SIMPLEBLOB, 0);
return sessKeyData;
}
В результате получаем зашифрованный симметричный сессионный ключ и два вектора инициализации. А вот с расшифровкой проблемы: Код:
public static byte[] decryptData(PCCERT_CONTEXT cert, CryptData cdata) throws CryptoException {
final KeyContext userKey = SignUtils.getUserKey(cert);
if (userKey == null)
throw new CryptoException("User key not found");
final Pointer sessKey = importSessionKey(userKey, cdata);
try {
final byte[] data = Advapi.cryptDecrypt(sessKey, null, true, 0, cdata.cryptedData);
return data;
} finally {
userKey.free();
}
}
private static Pointer importSessionKey(KeyContext userKey, CryptData cdata) throws CryptoException {
final Pointer hProv = userKey.getProvHandle();
// генерируем ефемерную пару
final Pointer ephemKey = Advapi.cryptGenKey(hProv, CALG_DH_EL_EPHEM, CRYPT_EXPORTABLE);
// Генерируем в 2 шага ключ согласования agreeKey. Для этого импортируем эфемерный открытый ключ, используя нашу ключевую пару.
// 1. Экспортируем эфемерный публичный ключ
final byte[] ephemPubKeyData = cryptExportKey(ephemKey, null, PUBLICKEYBLOB, 0);
// 2. Импортируем при помощи ключевой пары
final Pointer agreeKey = Advapi.cryptImportKey(hProv, ephemPubKeyData, userKey.getKeyHandle(), 0);
// устанавливаем вектор инициализации
cryptSetKeyParam(agreeKey, KP_IV, cdata.sv, 0);
// Импортируем симметричный ключ шифрования с использованием ключа согласования
final Pointer sessKey = cryptImportKey(hProv, cdata.ecnryptedKey, agreeKey, 0);
if (sessKey == null)
throw CryptoUtil.raiseCryptoError("cryptImportKey", getLastError()); // ОШИБКА ЗДЕСЬ. Bad data (0x80090005)
// Не забываем вектор инициализации
final byte[] ivData = cdata.iv;
cryptSetKeyParam(sessKey, KP_IV, ivData, 0);
return sessKey;
}
Возникает ошибка на этапе импорта сессионного ключа - Bad data (0x80090005). Что пропустил? Подвох в эфемерном ключе? Надо передавать его значение вместе со всеми данными? Или еще где ошибся? отступы почему-то пропали :( Отредактировано пользователем 16 августа 2013 г. 12:58:47(UTC)
| Причина: Не указана
|