Пожалуйста, не используйте симметричные ключи в исходных файлах. Вы можете использовать RSA, не вводя другой файл.В отличие от симметричных ключей, открытый ключ может быть жестко закодирован в исходном коде без каких-либо проблем с безопасностью, если вы можете гарантировать целостность исходного файла. Опять же, если кому-то удастся его изменить, дешифрование не будет работать или произойдет атака «человек-в-середине» (MITM) (и вы не узнаете об этом).
ПРЕДОСТЕРЕЖЕНИЯ
- Этот подход страдает от восприимчивости атаки MITM. Соответствующая контрмера должна заключаться в подписи данных, но тогда вы застряли в обращении с ключами, и это действительно отдельный вопрос.
- Ключи не навсегда, генерируемая вами пара ключей должна время от времени поворачиваться.
- Сделайте ключи достаточно большими (не менее 2048 бит).
- Отмена должна быть выполнена вами вручную. Если вам нужно более автоматическое решение, подумайте о PKI и OSCP Responders (с или без сшивания).
- Если данные, которые вы отправляете, являются большими, операции RSA будут длинными.
Хорошо, с этим из пути, давайте копать. Пример кода написан полностью с JDK 8.
Во-первых, генерировать пары ключей. Это должно быть сделано один раз или каждый раз, когда вам нужно повернуть:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = kpg.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
byte[] pubEnc = publicKey.getEncoded();
byte[] privKeyEnc = privateKey.getEncoded();
System.out.println(Base64.getEncoder().encodeToString(pubEnc));
System.out.println(Base64.getEncoder().encodeToString(privKeyEnc));
Скажем, открытый ключ был (это фактические ключи я сгенерированные, не использовать эти):
private static final String PUBLIC_KEY_BASE64 =
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGue
5TCdPJt08w7crbvWjfcSUy/xXjzjjjjPDP7D8PNSnn
CUeNcGWsR/Pd3eoBjmrAy/4Rl8JlHylRry8pX7Zpcz
iQB8wWQdpkSoArjeu4taeFn/45+eg4J5mzmIzFG9F5
wF7N+SeSvtq3E3Q0mtJRRZZJYgNkFmeDuOQjljJVZw
IDAQAB";
и закрытый ключ был:
private static final String PRIVATE_KEY_BASE64 =
"MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAg
EAAoGBAIa57lMJ08m3TzDtytu9aN9xJTL/FePOOOOM
8M/sPw81KecJR41wZaxH893d6gGOasDL/hGXwmUfKV
GvLylftmlzOJAHzBZB2mRKgCuN67i1p4Wf/jn56Dgn
mbOYjMUb0XnAXs35J5K+2rcTdDSa0lFFlkliA2QWZ4
O45COWMlVnAgMBAAECgYBAWTIRi1ISuHEkh48qoS8j
+eCwmNGVuvvFA55JUSdVVikrZm08iwCk5sD9qW6JS8
KFT2mMcZWxws5za171PffbeHoIFaNI5n5OXJa4meZA
cgl4ae5su89BjvfzDF2gsnBHwLpgsT0aVdIDQ5BGtL
WzRwZCogY6lZhBOQZAaNFYIQJBALr2+kT+pkSlxrrR
tMxK7WL+hNO7qOIl/CTBuAa6/zTtoEjFMFQBY//jH+
6iabHDfKpaFwh6ynZTXZsb7qIKOM8CQQC4eRAH1VEo
iofZNnX3VjiI5mLtV8rc8Jg+wznN+WFnwdNoLK8y9t
EcuKxg3neIJAM70D6l0IhBfza1QAqQh4/pAkA5vyLZ
wJV2SoWxGihvmQztMJOyGho1j2nrqHHAkm1U2bhSAa
XFrJBIbsxkFoHyx+BvdVf75IE4PtOAnwX7wpB9AkBQ
7CKBHS2N+D8hpQdYqcUBIPdyoFmIVC6lEaTw2x3Ekz
027KsqUyVmUQilMdIDsbCNc4uX14N+H90S43X+8sjJ
AkAKsvRbZ0Au9JytSRKSB7vYl37283zHoQ5jyYUE7x
g7C6nWSl1GEa6khZ47hFAj9C2bdLJ6GtjTleFsVCsR
LUoG";
клавиши выше, линия завернуты по причинам форматирования.
Скажем args[0]
был "attack at dawn!"
и ваш клиент выглядит следующим образом:
public static void main(String[] args) throws Exception {
byte[] pubKey = Base64.getDecoder().decode(PUBLIC_KEY_BASE64);
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(pubKey));
Cipher cipher = Cipher.getInstance("RSA");
Cipher.init(Cipher.ENCRYPT_MODE, publicKey);
String encryptedData = Base64.getEncoder().encodeToString(cipher.doFinal(args[0].getBytes("UTF-8")));
System.out.println("Encrypted data is: " + encryptedData);
}
Выход: Зашифрованные данные: cDoPpQYc6qibrBl5jdENcV + g6HslQDlo9potca5rQxecnxR3Bd/e1T0njqUMACl7x7AG3foGxqZyyUIMrOVXcnw/ux7BgQcg + RDZhSVFQAd5kUGI96pw8WtDVo1N1 + WEfaaPhK9CpwUKUxtwR0t27n + W0vhFCqNTEGhofLt8u9o =
Сервер:
public static void main(String[] args) throws Exception {
byte[] privKey = Base64.getDecoder().decode(PRIVATE_KEY_BASE64);
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privKey));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] encryptedData = Base64.getDecoder().decode(args[0]);
byte[] decryptedData = cipher.doFinal(encryptedData);
System.out.println("Decrypted message was: " + new String(decryptedData, "UTF-8"));
}
Выход: Расшифрованное сообщение было: атака на рассвете!
Одна классная вещь о реализации RSA в JDK является то, что он использует Optimal Asymmetric Encryption Padding (OAEP) с PKCS # 1, который имеет эффект, что даже идентичные сообщения будут отличаться от каждого шифрования.
Как и предыдущие комментаторы упомянули, не видя полную картину, могут возникнуть другие проблемы с безопасностью. Но для чего это стоит, я думаю, что этот подход лучше, чем использование симметричных ключей, которые все еще могут использоваться с этой схемой шифрования.Затем вы получите так называемую гибридную криптосистему , но есть API, которые делают это за вас.
Итак, вы хотите, чтобы ваша программа имела данные, но пользователь не так ли? Затем не отправляйте данные клиенту. Выполняйте обработку на сервере. – deviantfan
openSSL будет хорошим вариантом библиотеки для криптографии ..https: //www.openssl.org/docs/manmaster/crypto/crypto.html – basav
Посмотрите на этот учебник о том, как реализовать openssl https://www.ibm .com/developerworks/library/l-openssl/ – silvergasp