마지막으로 블로그를 쓴 이후로 오랜 시간이 걸렸다 고 생각합니다. 먼저 불평하겠습니다. 이번 달 에이 회사는 초과 근무, 출판 및 출판을 출판하고 출판을 시작했으며 새로운 프로젝트가 너무 빡빡해서 특정 프로젝트에 대해별로 말하지 않을 것입니다. 오늘날 비대칭 암호화에 대해 이야기하는 것이 정말 중요합니다. 비대칭 암호화는 우리의 일상에서 필수적입니다.
개념
RSA에 대해 이야기하기 전에 먼저 비대칭 암호화가 무엇인지 이야기합시다. 대칭 암호화에 대해 이야기 할 때, 대칭 암호화 알고리즘은 암호화 및 암호를 암호화 할 때 동일한 비밀 키를 사용한다고 말했으며, 두 당사자는 암호화 및 암호를 암호화하고 암호화해야합니다. 비대칭 암호화는 그렇지 않습니다. 비대칭 암호화 알고리즘에는 두 개의 키가 암호화 및 해독, 즉 공개 키와 개인 키가 필요합니다.
주목할만한 점은 공개 키와 개인 키가 쌍이어야한다는 것입니다. 데이터가 공개 키로 암호화되면 해당 개인 키 만 해독 할 수 있으며 그 반대도 마찬가지입니다. 암호화와 암호 해독은 두 가지 다른 키를 사용하기 때문에이 알고리즘을 비대칭 암호화 알고리즘이라고합니다.
작업 과정
아래 그림과 같이, 데이터는 비대칭 암호화를 사용하여 전송됩니다.
비대칭 암호화에 사용되는 주요 알고리즘에는 RSA, Elgamal, 배낭 알고리즘, Rabin, DH, ECC (타원 곡선 암호화 알고리즘) 등이 포함됩니다. 오늘날 우리는 주로 RSA를 소개합니다. 다른 알고리즘은 나중에 소개하기 위해 몇 가지를 선택할 것입니다.
RSA
실제로 RSA는 1978 년 초에 나타 났으며 데이터 암호화와 디지털 서명 모두에 사용할 수있는 최초의 알고리즘이었습니다. 이해하고 운영하기 쉽고 매우 인기가 있습니다. 원칙은 위의 작업 과정에서 설명 된대로입니다.
RSA 알고리즘은 매우 간단한 숫자 이론 사실을 기반으로합니다. 두 개의 큰 소수를 쉽게 곱하기 쉽지만 제품을 고려하는 것은 매우 어렵 기 때문에 제품을 암호화 키로 공개 할 수 있습니다.
코드 구현
아래의 특정 코드 구현을 살펴 보겠습니다.
import com.google.common.collect.maps; import sun.misc.base64decoder; import sun.misc.base64encoder; javax.crypto.cipher 가져 오기; java.security import.*; java.security.interfaces.rsaprivatekey 가져 오기; java.security.interfaces.rsapublickey 가져 오기; java.security.spec.pkcs8encodedkeyspec import; import java.security.spec.x509encodedKeyspec; java.util.map import; /*** 2015/3/3에 Xiang.li가 작성했습니다. * RSA 암호화 및 암호 해독 도구 클래스*/ public class rsa {/ *** 판결 방법*/ 개인 최종 정적 문자열 key_rsa = "rsa"; / *** 서명 알고리즘 정의*/ 개인 최종 정적 문자열 key_rsa_signature = "md5withrsa"; / *** 공개 키 알고리즘 정의*/ 개인 최종 정적 문자열 key_rsa_publickey = "rsapublickey"; / *** 개인 키 알고리즘 정의*/ 개인 최종 정적 문자열 key_rsa_privatekey = "rsaprivatekey"; / *** 초기화 키* @return*/ public static map <String, object> init () {map <String, Object> map = null; {kyypairgenerator generator generator = kyypairgenerator.getinstance (key_rsa); Generator.initialize (1024); Keypair kyypair = generator.generatekeypair (); // 공개 키 rsapublickey publickey = (rsapublickey) kyypair.getPublic (); // 개인 키 rsaprivatekey privatekey = (rsaprivatekey) kyypair.getPrivate (); // 키를지도 맵 = 맵으로 캡슐화합니다. newhashmap (); map.put (key_rsa_publickey, publickey); map.put (key_rsa_privatekey, privatekey); } catch (nosuchalgorithmexception e) {e.printstacktrace (); } 리턴 맵; } / *** 개인 키를 사용하여 정보에 대한 디지털 서명을 생성하십시오* @param 데이터 암호화 데이터* @param privatekey private key* @return* / public static string sign (byte [] data, string privatekey) {String str = ""; 시도 {// 개인 키를 인코딩 된 BYTE [] bytes = decryptbase64 (privatekey)를 해독합니다. // PKCS8ENCODEDKEYSPEC 객체 구성 PKCS8ENCODEDKEYSPEC PKCS = NEW PKCS8ENCODEDKEYSPEC (BYTES); // 지정된 암호화 알고리즘 keyfactory factory = keyfactory.getInstance (key_rsa); // 개인 키 객체를 가져옵니다. privatekey key = factory.generate -private (pkcs); // 프라이빗 키를 사용하여 정보 서명에 대한 디지털 서명을 생성합니다. 서명 = signature.getInstance (key_rsa_signature); Signature.initsign (키); 서명 .update (데이터); str = encryptbase64 (signature.sign ()); } catch (예외 e) {e.printstacktrace (); } return str; } / *** 디지털 서명 확인* @param 데이터 암호화 데이터* @param publickey public Key* @param 부호 디지털 서명* @return 성공적인 반환 true, 실패한 반환 거짓* / public static boolean verify (byte [] data, string publickey, String sign) {boolean flag = false; try {// 공개 키를 암호화하는 바이트를 암호화합니다 [] bytes = decryptbase64 (publickey); // X509ENCODEDKEYSPEC 객체 X509ONCODEDKEYSPEC KEYSPEC = NEW X509ENCODEDKEYSPEC (BYTES); // 지정된 암호화 알고리즘 keyfactory factory = keyfactory.getInstance (key_rsa); // 공개 키 객체 가져 오기 publickey key = factory.generatepublic (keyspec); // 공개 키 서명 서명으로 디지털 서명을 확인합니다. signature.initverify (키); 서명 .update (데이터); flag = signature.verify (decryptbase64 (sign)); } catch (예외 e) {e.printstacktrace (); } 반환 플래그; } / *** private key decrypt* @param data 암호화 데이터* @param 키 개인 키* @return* / public static byte [] decryptbyPrivatekey (byte [] data, string key) {byte [] result = null; try {// 개인 키 바이트를 해독합니다 [] bytes = decryptbase64 (키); // 개인 키를 얻습니다. keyfactory factory = keyfactory.getInstance (key_rsa); PrivateKey PrivateKey = factory.generate -Private (Keyspec); // Data Cipher Cipher = cipher.getInstance (incatory.getalgorithm ())을 해독합니다. cipher.init (cipher.decrypt_mode, privatekey); 결과 = cipher.dofinal (데이터); } catch (예외 e) {e.printstacktrace (); } 반환 결과; } / *** 개인 키 암호 해독* @param 데이터 암호화 데이터* @param 키 공개 키* @return* / public static byte [] decryptbypublickey (byte [] data, string key) {byte [] result = null; try {// 공개 키 바이트를 해독합니다 [] bytes = decryptbase64 (key); // 공개 키 X509ENCODEDKEYSPEC KEYSSPEC = NEW X509ENCODEDKEYSPEC (바이트); keyfactory factory = keyfactory.getInstance (key_rsa); publickey publickey = factory.generatepublic (Keyspec); // Data Cipher Cipher = cipher.getInstance (incatory.getalgorithm ())을 해독합니다. cipher.init (cipher.decrypt_mode, publickey); 결과 = cipher.dofinal (데이터); } catch (예외 e) {e.printstacktrace (); } 반환 결과; } / *** 공개 키 암호화* @param 데이터 암호화* @param 키 공개 키* @return* / public static byte [] alcryptbypublickey (byte [] data, string key) {byte [] result = null; try {byte [] bytes = decryptbase64 (키); // 공개 키 X509ENCODEDKEYSPEC KEYSSPEC = NEW X509ENCODEDKEYSPEC (바이트); keyfactory factory = keyfactory.getInstance (key_rsa); publickey publickey = factory.generatepublic (Keyspec); // 데이터 암호화 cipher cipher = cipher.getInstance (factory.getalgorithm ()); cipher.init (cipher.encrypt_mode, publickey); 결과 = cipher.dofinal (데이터); } catch (예외 e) {e.printstacktrace (); } 반환 결과; } / *** 개인 키 암호화* @param 데이터 암호화 할* @param 키 개인 키* @return* / public static byte [] EncryptByPrivatekey (byte [] data, string key) {byte [] result = null; try {byte [] bytes = decryptbase64 (키); // 개인 키를 가져옵니다. keyfactory factory = keyfactory.getInstance (key_rsa); PrivateKey PrivateKey = factory.generate -Private (Keyspec); // 데이터 암호화 cipher cipher = cipher.getInstance (factory.getalgorithm ()); cipher.init (cipher.encrypt_mode, privatekey); 결과 = cipher.dofinal (데이터); } catch (예외 e) {e.printstacktrace (); } 반환 결과; } / ** * 공개 키를 가져옵니다 * @param map * @return * / public static string getPublickey (map <String, Object> Map) {String str = ""; {key key = (key) map.get (key_rsa_publickey); str = encryptbase64 (key.getencoded ()); } catch (예외 e) {e.printstacktrace (); } return str; } / ** * 개인 키를 가져옵니다 * @param map * @return * / public static string getPrivatekey (map <String, Object> Map) {String str = ""; try {key key = (key) map.get (key_rsa_privatekey); str = encryptbase64 (key.getencoded ()); } catch (예외 e) {e.printstacktrace (); } return str; } / *** Base64 Decrypt* @param 키 문자열* @return byte array* @throws Exception* / public static byte [] decryptbase64 (String Key)는 예외 {return (new Base64decoder ()). DecodeBuffer (키); } / *** base64 암호화* @param 키 바이트 배열* @return String* @throws Exception* / public static string encryptbase64 (byte [] 키) 예외 {return (new Base64Encoder ()). EncodeBuffer (key); } / *** 테스트 방법* @param args* / public static void main (String [] args) {String privatekey = ""; 문자열 publickey = ""; // 공개 키 개인 키 맵 생성 <문자열, 객체> map = init (); publickey = getPublickey (지도); privatekey = getPrivateKey (지도); System.out.println ( "공개 키 : /n /r" + publickey); System.out.println ( "개인 키 : /n /r" + privatekey); System.out.println("Public key encryption------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- "; byte[] encWord = EncryptByPublickey (Word.getBytes (), publickey); encryption---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- EncryptByPrivateKey (English.GetBytes (), PrivateKey); 문자열 decenglish = new String (decryptbypublickey (Engenglish, publickey)); System.out.println ( "암호화 전 :" + English + "/n/r" + "암호 해독 후 :" + decenglish); System.out.println ( "개인 키 시그니처-공개 키 검증 서명"); // 서명 string 부호를 생성합니다 = 부호 (Engenglish, privatekey); System.out.println ( "서명 :/r" + 부호); // 서명 부울 상태 확인 = verify (encenglish, publickey, sign); System.out.println ( "상태 :/r" + 상태); }} 암호화 및 해독 결과
결론
실제로, 겉보기에는 복잡한 프로세스가 한 문장으로 설명 될 수 있습니다. 공개 키 암호화 및 개인 키 암호 해독 사용, 당사자 B에서 당사자 A로의 데이터 전송은 개인 키 암호화 및 공개 키 암호 해독을 통해 완료되며, 동시에 개인 키 시그니처 및 공개 키 검증 서명을 통해 당사자 A의 데이터 전송 및 검증이 완료되고 두 개의 데이터 전송이 완료됩니다.
비대칭 암호화 알고리즘의 출현은 하나의 키만 암호화하고 해독하는 문제를 해결하는 것입니다. 이 키가 손실되거나 공개되는 한 암호화 된 데이터는 쉽게 공격됩니다. 동시에, 그것은 후속 디지털 서명, 디지털 인증서 등이 얻어지는 비대칭 암호화 알고리즘의 출현으로 인해 정확히 있습니다.
좋아, 오늘 여기서 멈추자. 다음 기사는 비대칭 암호화를 계속합니다. 어느 쪽이든, 나는 그 당시에 알게 될 것입니다. 먼저 여기에 비밀을 유지하십시오