Криптография Java / Ошибка безопасности
У меня есть некоторый код ниже, который должен создать хеш сообщения с использованием SHA1, распечатать хеш, зашифровать сообщение с помощью алгоритма RSA, распечатать зашифрованное сообщение, затем расшифровать сообщение и снова напечатать хэш. Первое и третье сообщения печати должны совпадать, поскольку они оба являются незашифрованным хешем исходного сообщения, но в моем коде они не совпадают - кто-нибудь может сказать мне, почему? Благодарю. Мой код выглядит следующим образом:
String input = "input message test";
MessageDigest hash = MessageDigest.getInstance("SHA1");
hash.update(Utils.toByteArray(input));
System.out.println("digest : " +hash.digest());
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
SecureRandom random = new SecureRandom();
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(512, random);
KeyPair pair = generator.generateKeyPair();
Key pubKey = pair.getPublic();
Key privKey = pair.getPrivate();
cipher.init(Cipher.ENCRYPT_MODE, privKey);
byte[] ciphertext = cipher.doFinal(hash.digest());
System.out.println("cipher: " + ciphertext);
cipher.init(Cipher.DECRYPT_MODE, pubKey);
byte[] plaintext = cipher.doFinal(ciphertext);
System.out.println("plaintext : " + plaintext);
Обновление: у меня уже есть, я просто удалил, как это было во втором файле. Мой метод:
public static String toHex(byte[] data, int length) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i != length; i++) {
int v = data[i] & 0xff;
buf.append(digits.charAt(v >> 4));
buf.append(digits.charAt(v & 0xf));
}
return buf.toString();
}
Но это возвращает:
digest : b2cad21e87dbd57f1a1928e4013b56fb553bb82a
cipher: 502cffa545bda39f677b72f677f1a6a4308a329747a8f4de9b0d1ffd83fcec10c5b41a218201e204c7949b45a8119eb42e6ab5dc0c97f97b6d59600632d2b2ad
plaintext : da39a3ee5e6b4b0d3255bfef95601890afd80709
1 ответ
Дайджест хеша нужно сделать только один раз ( см. Документ):
System.out.println("digest : " + hash.digest()); //1
byte[] ciphertext = cipher.doFinal(hash.digest()); //2
призвание hash.digest()
один раз создает дайджест, а затем сбрасывает хеш-объект. Вот почему вы получаете другой результат.
Ниже приведено изменение, которое я сделал:
byte[] inputHash = hash.digest();
System.out.println("digest : " + bytesToHex(inputHash));
byte[] ciphertext = cipher.doFinal(inputHash);
Вот вывод, который я получаю:
digest : 4b03b72ccc3b238e3df3c0a9dcb8d03fd6417848
plaintext : 4b03b72ccc3b238e3df3c0a9dcb8d03fd6417848
Вы можете использовать любой байтовый массив в шестнадцатеричный формат. Ниже приведен фрагмент, который вы можете использовать:
public static String bytesToHex(byte[] hash) {
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if(hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}