Концепция асимметричного пароля
1. Основное отличие от алгоритмов симметричного шифрования состоит в том, что клавиши шифрования и дешифрования различны, один из них является общедоступным (открытый ключ), а другой - конфиденциально (закрытый ключ). В основном он решает проблему управления распределением ключевых алгоритмов симметричного шифрования и повышает безопасность алгоритма.
2. Эффективность шифрования и дешифрования алгоритмов асимметричного шифрования относительно низкая. В дизайне алгоритма асимметричные алгоритмы шифрования имеют строгие требования к длине зашифрованных данных. Например, алгоритм RSA требует, чтобы данные были зашифрованы не более 53 байтов.
3. Алгоритмы асимметричного шифрования в основном используются для обмена ключами симметричных алгоритмов шифрования, а не для обмена данными.
4. Java6 предоставляет два алгоритма, которые реализуют DH и RSA. Bouncy Castle обеспечивает поддержку алгоритма E1GAMAL. В дополнение к тремя вышеуказанными алгоритмами, существует также алгоритм ECC, и в настоящее время не существует соответствующего компонента с открытым исходным кодом для обеспечения поддержки.
Два клавиша требуются для шифрования или дешифрования, разделенных на государственные и частные ключи
Особенности: высокая безопасность, медленная скорость
использовать
【Обмен ключами (DH)】
Без определения общего ключа обе стороны генерируют ключ и не обеспечивают работу шифрования. Шифрование и дешифрование также требуют других симметричных алгоритмов шифрования для реализации.
Пример алгоритма DH
Импорт javax.crypto.keyagreement; import javax.crypto.interfaces.dhprivatekey; импорт javax.crypto.interfaces.dhpublickey; импорт javax.crypto.spec.dhparameterspec; импорт java.security. java.security.spec.x509encodedkeyspec; import java.util.hashmap; import java.util.map; // 1 Сгенерировать исходный ключ // 2 Общедоступный ключ источника передается цели, и цель генерирует открытый ключ и закрытый ключ через источник. // 3 Общедоступный ключ цели передается источнику // 4 обе стороны используют открытый ключ другой стороны и его собственный личный ключ для генерации локального ключа // 5 Если обе стороны генерируют локальный ключ одинаково, завершите обмен клавишами обмен Dhutil {public Static Final String public_key = "dh_public_key"; Public Static Final String private_key = "dh_private_key"; /** * Сгенерировать пару исходных клавиш * @return * @Throws Exception */public Static Map <String, Object> initSourceKey () Throws Exception {// Создание экземпляра KeyPairgenerator, выберите KeyPairgenerator KeyPairGenerator DH ("DH"); // Инициализировать длину ключа, по умолчанию 1024, необязательный диапазон 512-65536 и мультипликации 64 Keypairgenerator.initialize (1024); // генерировать клавиш -клавиши пары ключей = KeyPairGenerator.GenerateKeyPair (); Dhpublickey dhpublickey = (dhpublickey) keypair.getpublic (); Dhprivatekey dhprivatekey = (dhprivatekey) keypair.getprivate (); // Поместите пару клавиш в карту карты <строка, объект> keymap = new Hashmap <String, Object> (); keymap.put (public_key, dhpublickey); keymap.put (private_key, dhprivatekey); вернуть Кеймап; } / ** * Сгенерировать пару целевых ключей через источник открытого ключа * @param sourcepublickey * @return * @throhs Exception * / public Static Map <String, Object> inittargetKey (byte [] sourcepublickey) throws Exception {keyFactory keyFactory = keyFactory.getNstance ("dh"); // Использование источника открытого ключа, генерируйте KeySpec и используйте KeyFactory для генерации источника PublicKey Information x509encodeDkeySpec keyspec = new x509encodkeyspec (sourcepublickey); Dhpublickey sourcepublic = (dhpublickey) keyfactory.generatepublic (keyspec); Dhparameterspec dhpublickeyparams = sourcepublic.getparams (); KeyPairGenerator KeyPairGenerator = KeyPairGenerator.getInstance ("DH"); keypairgenerator.initialize (dhpublickeyparams); Клавиша клавиши = KeyPairGenerator.GenerateKeyPair (); Dhpublickey dhpublickey = (dhpublickey) keypair.getpublic (); Dhprivatekey dhprivatekey = (dhprivatekey) keypair.getprivate (); // Поместите пару клавиш в карту карты <строка, объект> keymap = new Hashmap <String, Object> (); keymap.put (public_key, dhpublickey); keymap.put (private_key, dhprivatekey); вернуть Кеймап; } / *** Используйте открытый ключ одной стороны и личный ключ другой стороны, чтобы сгенерировать локальный ключ* @return* / public Static Byte [] GenerateLocalSecretKey (byte [] apublickey, byte [] bprivatekey) бросает исключение {keyfactory keyfactory = keyfactory.getinstance ("dh"); // Используйте открытый ключ, генерируйте KeySpec и используйте KeyFactory для генерации информации, связанной с PublicKey, x509EncodkeySpec keyspec = new x509encodkeyspec (apublickey); Publickey publickey = keyfactory.generatepublic (keyspec); // Использование B Private Key, генерируйте B -частную информацию, связанную с pkcs8codedkeyspec pkcs8encodedkeyspec = new Pkcs8encodeDkeySpec (bprivateKey); PrivateKey PrivateKey = keyFactory.GeneratePrivate (PKCS8encodeDkeySpec); // Encrypt A PublicKey и B PrivateKey через KeyAgreement Keyagreement KeyAgreement = KeyAgreement.getInstance ("DH"); KeyAgreement.init (privateKey); KeyAgreement.dophase (publickey, true); return quecreement.generatesecret ("aes"). getEncoded (); // Алгоритм использует алгоритм симметричного шифрования (des, desede, aes) // return geoAgreement.generateSecret (); // Алгоритм также можно использовать для расчета с использованием метода по умолчанию без выбора алгоритма} // Получить общедоступный статический байт байта [] getPublickey (map <String, Object> Map) {(DHPublickey) map.get (public_key)). GetEncoded (); } // Получите закрытый ключ байт массив общедоступный статический байт [] getPrivateKey (map <string, object> map) {return ((dhprivateKey) map.get (private_key)). GetEncoded (); } public static void main (string [] args) бросает исключение {byte [] source_public_key; byte [] source_private_key; byte [] source_local_key; byte [] target_public_key; byte [] target_private_key; byte [] target_local_key; Map <string, object> sourcekey = initsourcekey (); Source_public_key = getPublickey (SourceKey); source_private_key = getPrivateKey (SourceKey); System.out.println ("Source Public Key:"+bytestohex.frombyteStohex (source_public_key)); System.out.println ("Source Private Key:"+bytestohex.frombyteStohex (source_private_key)); Map <string, object> targetkey = inittargetkey (getPublickey (SourceKey)); target_public_key = getPublickey (TargetKey); target_private_key = getPrivateKey (TargetKey); System.out.println ("Target Public Key:"+ByteStohex.FromByTeStoHex (target_public_key)); System.out.println ("Target Private Key:"+bytestohex.frombyteStohex (target_private_key)); source_local_key = generateLocalsecretkey (target_public_key, source_private_key); target_local_key = generateLocalsecretkey (source_public_key, target_private_key); System.out.println («Исходный локальный ключ:»+bytestohex.frombytestohex (source_local_key)); System.out.println ("Target Local Key:"+bytestohex.frombyteStohex (target_local_key)); }}【Шифрование/дешифрование (RSA) 】【 Цифровая подпись (RSA)】
Алгоритм RSA позже, чем алгоритм DH, и все эти пять букв являются первыми буквами человеческого имени. Алгоритм DH является первой асимметричной криптографической системой.
Алгоритм RSA имеет медленную скорость вычисления и не подходит для шифрования больших объемов данных. Одним из решений является смешивание методов RSA и симметричного шифрования, данных шифрования с использованием симметричных методов шифрования, а симметричные клавиши шифрования шифруются с использованием алгоритмов RSA. Поскольку ключ очень короткий, время не слишком много. Фактически, единственным недостатком симметричных методов шифрования является то, что ключ сложно пройти, а симметричные методы шифрования также трудно взломать.
Применимые сценарии RSA:
(1) Сервер генерирует открытый ключ и закрытый ключ и публикует открытый ключ.
(2) Клиент использует открытый ключ для шифрования данных и передачи их на сервер. Другие не могут понять зашифрованные данные.
(3) Сервер использует закрытый ключ для расшифровки данных и просмотра данных, представленных пользователем.
В этом случае открытый ключ похож на почтовый ящик, и каждый может поместить сообщение в этот почтовый ящик, но только те, у кого есть ключи для почтового ящика, могут разксимировать и просматривать буквы в этом почтовом ящике.
RSA применимого сценария 2:
(1) Император генерирует открытый ключ и секретный ключ и публикует открытый ключ.
(2) Император выпустил указ, чтобы информировать мир. В нижнем правом углу указания есть две строки чисел. Первая строка - это случайная строка, а вторая строка - результат шифрования первой строки с закрытым ключом.
(3) Некоторые люди не верят, что указ был написан императором, поэтому они расшифровали вторую строку чисел, используя открытый ключ. После расшифровки они обнаружили, что это было то же самое, что и первая строка чисел, что означает, что он действительно был написан императором. Поскольку у большинства людей нет ключа, они не могут зашифровать данные, которые могут быть расшифрованы с помощью открытого ключа.
В этом случае открытый ключ используется для дешифрования, а закрытый ключ используется для шифрования. Это может быть использовано, чтобы доказать, что объявление действительно было отправлено кем -то. Это эквивалентно подписи.
На самом деле, нет необходимости быть особенно долго для подписей. Вообще говоря, подписи имеют фиксированную длину. Если вы хотите иметь фиксированную длину, вы можете использовать алгоритм MessageDigest, такой как серия MD5 и SHA. Следовательно, существует множество алгоритмов подписи, таких как MD5 WithRSA и т. Д.
Примеры шифрования/дешифрования RSA
Импорт javax.crypto.cipher; импорт java.security.keypair; импорт java.security.keypairgenerator; импорт java.security.publickey; импорт java.security.interfaces.rsaprivatekey; импорт java.security.Interfaces.rsapublickey; java.util.map;/*** инструмент шифрования RSA*/public class rsautil {public Static Final String public_key = "rsa_public_key"; public Static Final String private_key = "rsa_private_key"; / ** * Ключ инициализации * @return * @Throws Exception */ public Static Map <String, Object> initKey () Throws Exception {KeyPairGenerator KeyPairGenerator = keyPairGenerator.getInstance ("rsa"); keypairgenerator.initialize (1024); // 512-65536 & Multiples из 64 клавиши Keypair = KeyPairgenerator.GenerateKeyPair (); Rsapublickey publickey = (rsapublickey) keypair.getPublic (); Rsaprivatekey privatekey = (rsaprivatekey) keypair.getPrivate (); Map <string, object> keymap = new hashmap <string, object> (); keymap.put (public_key, publickey); keymap.put (private_key, privatekey); вернуть Кеймап; } public static rsapublickey getPublickey (map <string, object> keymap) {return (rsapublickey) keymap.get (public_key); } public static rsaprivateKey getPrivateKey (map <string, object> keymap) {return (rsaprivatekey) keymap.get (private_key); } / ** * Encrypt Data с использованием открытого ключа * @param Data * @param publickey * @return * @throws Exception * / public Static Byte [] Encrypt (byte [] data, rsapublickey publickey) бросает исключение {cipher cipher = cipher.getNstance ("rsa"); cipher.init (cipher.encrypt_mode, publickey); return cipher.dofinal (data); } / ** * Используйте закрытый ключ для расшифровки * @param data * @param privatekey * @return * @throws exception * / public static byte [] decrypt (byte [] data, rsaprivatekey privatekey) throws exection {cipher cipher = cipher.getinstance ("rsa"); cipher.init (cipher.decrypt_mode, privatekey); return cipher.dofinal (data); } public static void main (string [] args) бросает исключение {String data = "Jay Chou-Dongfeng Break"; Map <string, object> keymap = initKey (); byte [] miwen = incrypt (data.getbytes (), getpublickey (keymap)); System.out.println ("зашифрованное контент:"+bytestohex.frombytestohex (miwen)); byte [] plain = decrypt (miwen, getprivatekey (keymap)); System.out.println ("расшифрованное контент:"+new String (plain)); }}Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.