SSH 모드 암호화를 구현하는 Java의 구현 원리 및 아이디어가 귀하와 공유됩니다.
1. SSH 암호화 원리
SSH는 먼저 비대칭 암호화를 통해 서버 비대칭 암호화 비밀번호를 지시 한 다음 양 당사자가 이미 암호화 및 암호 해독에 대해 알고있는 암호화 암호를 사용합니다. 아래 그림을 참조하십시오.
설명 : SSH에서 비대칭 암호화 및 대칭 암호화를 사용해야하는 이유는 무엇입니까? 그것의 사용은 무엇입니까? 안전합니까? 그런 다음 대칭 암호화를 사용했습니다. 왜 처음에는 비대칭 암호화를 사용 했습니까? 반면, 비대칭 암호화가 사용되므로 대칭 암호화를 사용해야하는 이유는 무엇입니까?
비대칭 암호화는 클라이언트가 생성 한 256 비트 임의 비밀번호를 서버로 전달하는 것입니다. 그런 다음 배송 과정에서 공개 키는 암호화에 사용 되므로이 256 비트 암호화 암호가 네트워크에 크랙하기가 어렵습니다.
비대칭 암호화를 자주 사용하는 것은 성능 낭비이기 때문에 SSH는 사용자 이름과 암호를 다음에 전달할 때 암호화 된 암호로 256 비트 길이의 암호를 사용하기 때문에 대칭 암호화입니다. 나는 모든 사람들이 균열의 어려움을 알고 있다고 생각하며 각 비트마다 0-9 변경이 있습니다.
이것은 안전합니까? 나는 그것이 여전히 매우 좋다고 생각하며, 사용될 때 이해하기 쉽습니다.
2. 나의 SSH 암호화 원리
①, 사용 시나리오
내가 개발 한 프로젝트는 대량 선물 거래로, 주로 교환에 서비스를 제공하여 소프트웨어를 사용하여 교환주기를 제어해야한다는 요구를 만듭니다. 다시 말해, 프로젝트에는 프로젝트주기를 제어하는 백도어가 있습니다. Exchange가 소프트웨어주기를 사용하는 경우 소프트웨어주기가 갱신되지 않고 다른 사람의 서버에 프로젝트 코드를 배포하면 제어하기가 어려울 것입니다. 그러나이 백도어를 사용하면 소프트웨어가 만료 된 후 자동으로 중지되므로 교환이 우리에게 돈을주지 않을 것이라고 걱정하지 않습니다.
②, 사용법
트랜잭션에 제공하는 프로젝트 코드에는 백도어가 포함되어 있으며 웹 서비스 클라이언트를 통해 웹 서비스에 요청을 보냅니다.
요청을받은 후 웹 서비스는 클라이언트가 필요한 정보를 반환합니다.
위의 프로세스에서는 SSH 암호화 요청 방법이 생성됩니다. 서투른 인물을 사용하여 그것을 표현할 수 있습니다.
3. 내 SSH 구현
WebService를 사용하려면 웹 서비스 서비스와 웹 서비스 클라이언트를 설정해야합니다. 나는 당분간 이것에 대해 너무 많이 말하고 싶지 않습니다. 여러 가지 방법이 있기 때문에 여기에 모든 사람을 오도하지 않을 것입니다. 나는 일식을 통해 그것을했고 웹 서비스 사이의 통신을 참조 할 수 있습니다.
다음으로 코드를 소개하지만 길이 문제를 고려하면 불필요한 코드를 게시하지 않습니다. 열쇠는이 원리를 명확하게 설명하는 것입니다.
①, 서비스
Exchanservice.java
public byte [] request (문자열 param, string resulttype) {logger.info ( "요청 매개 변수 :" + param); // 리턴 객체 Keyresult Keyresult = New Keyresult (); {// 공개 키를 먼저 가져옵니다. // 공개 및 개인 키 생성 privatekey = rsacoder.getPrivateKey (keymap); kyresult.setkey (rsacoder.getPublickey (keyp)); logger.info ( "공개 키 문자열 :" + kyresult.getKey ()); logger.info ( "개인 키 문자열 :" + privatekey); } else if (resulttype.equals (eCHOSTR_RESULT_TYPE)) {// 클라이언트 바이트의 비밀번호 정보를 설정합니다 [] parambyte = new Base64DecoDer (). DecodeBuffer (param); echostr = new String (rsacoder.decryptbyPrivatekey (Parambyte, PrivateKey)); } else {// 데이터베이스를 통해 교환에 해당하는 권한 정보를 가져옵니다. // 먼저 요청을 바이트 배열로 변환 한 다음 해독 한 다음 마지막으로 문자열 exchangeInfo info = exchangeInfo.dao.getInfoByname (new String (cryptutil.decrypt (새 base64decoder (). decodebuffer (param), echostr.getBytes ())로 변환합니다. 문자열 결과 = ""; // (resulttype.equals (privilege_result_type)) {// 사용 날짜를 판단 할 때 // 사용 날짜를 판단 할 때 // 현재 로그인의 현재 날짜와 시작 날짜를 비교하기 위해 비교할 수있는 날짜를 계산할 수있는 날짜를 계산할 수있는 날짜를 계산할 때 () (newtime ()/ 100)을 계산할 때 사용 날짜를 판단 할 때 // 사용 날짜를 판단 할 때 시스템 활성화 권한을 가져옵니다. // 일로 변환 int day = (int) (시간 / (60 * 60 * 24)); // (usedays -day> 0) {// result = "1"을 사용할 수 있습니다. } else {// result = "0"을 사용할 수 없습니다. }} keyresult.setResult (cryptutil.encrypt (result.getBytes (), echostr.getBytes ())); } return jsonutil.objecttobyte (Keyresult); } catch (예외 e) {logger.error ( "웹 서비스 오류 !!!"); logger.error (e.getMessage (), e); } return null;}자세히 설명하겠습니다.
첫 번째 판단 진술의 내용은 공개 및 개인 키를 생성하고 공개 키를 반환하는 것입니다.
두 번째 판단 진술의 내용은 클라이언트가 보낸 임의 문자열을 저장하는 것입니다. 이 단계는 매우 중요합니다. 임의의 문자열은 먼저 공개 키로 암호화되어 암호화 깊이를 크게 향상시킵니다.
세 번째 판단 진술의 내용은 임의의 문자열을 통해 클라이언트의 권한을 암호화하는 것입니다.
②, 클라이언트
Exchangeutil.java
public static boolean canrunforexchange (string resulttype) {int i = 1; 부울 결과 = 거짓; while (true) {try {// webservice 호출 클래스 exchangeserviceproxy proxy = new ExchangeserviceProxy (); Base64encoder encoder = 새로운 Base64encoder (); // 단계 1. 서비스 Keyresult kyresult = jsonutil.bytetoobject (proxy.request (null, public_key_result_type), keyresult.class)에 의해 생성 된 공개 키를 얻으십시오. // step2. 임의의 문자열을 생성하여 webserivce 문자열 echostr = strutil.getechostrbylength (10)로 보냅니다. 바이트 [] echobyteparam = rsacoder.encryptbypublickey (echostr.getBytes (), kyresult.getKey ()); proxy.request (encoder.encode (echobyteparam), echostr_result_type); // step3. 클라이언트 요청 정보를 암호화하고 WebService로 보내기 // 먼저 바이트 배열로 암호화 한 다음 문자열 바이트로 변환 한 다음 [] results = proxy.request (encoder.encode (cryptutil.encrypt (constants.client_type.getBype.getBype.getBytes ())); kyresult = jsonutil.bytetoobject (results, kyresult.class); // step4. 비밀번호 암호 해독 서버 문자열 응답을 통해 메시지를 반환합니다 = 새 문자열 (cryptutil.decrypt (keyresult.getResult (), echostr.getBytes ())); if (response.equals ( "1")) {result = true; } 부서지다; } catch (예외 e) {logger.debug ( "th" + i + "시간로드 웹 서비스 실패"); i ++; logger.error (e.getMessage (), e); if (i> = 10) {break; }}} return result;}간단한 설명 :
루프는 주로 네트워크가 분리 될 때 서비스가 요청을 지속적으로 전송하는 것을 방지하고 최대 10 배까지 충분합니다.
네 가지 주요 단계가 있으며 의견에서 설명하고 싶은 것은 괜찮습니다.
public 공개 암호화 및 암호 해독
cryptutil.java
package com.honzh.socket.util; import javax.crypto.cipher; import javax.crypto.secretkey; import javax.crypto.secretkeyfactory; import javax.crypto.spec.deskeyspec; import javax.crypto.spec.ivparameterspec. 암호화 * @description : encrypt * @param data * @param key * @return * @throws 예외 */ public static byte [] alcrypt (byte [] data, byte [] key) 예외 {key = get8 (key); Cipher Cipher = cipher.getinstance ( "des/cbc/pkcs5padding"); Deskeyspec Deskeyspec = 새로운 Deskeyspec (키); Secretkey keyfactory = secretkeyFactory.getInstance ( "des"); Secretkey Secretkey = keyfactory.generatesecret (Deskeyspec); ivparameterspec iv = 새로운 ivparameterspec (키); cipher.init (cipher.encrypt_mode, secretkey, iv); 반환 cipher.dofinal (데이터); } / ** * @title : decrypt * @description : decrypt * @param data * @param key * @return * @throws 예외 * / public static byryp [] decrypt (byte [] data, byte [] key) 예외 {key = get8 (key); Cipher Cipher = cipher.getinstance ( "des/cbc/pkcs5padding"); Deskeyspec Deskeyspec = 새로운 Deskeyspec (키); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance ( "des"); Secretkey Secretkey = keyfactory.generatesecret (Deskeyspec); ivparameterspec iv = 새로운 ivparameterspec (키); cipher.init (cipher.decrypt_mode, secretkey, iv); 반환 cipher.dofinal (데이터); } private static byte [] get8 (byte [] key) {byte [] key1 = new Byte [8]; for (int i = 0; i <8; i ++) {key1 [i] = key [i]; } return key1; } public static String toHexString (byte [] data) {String s = ""; for (int i = 0; i <data.length; i ++) {s+= integer.tohexstring (data [i] & 0xff)+"-"; } 반환 s; }} 일반적으로 SHA 및 MD5 암호화는 우리가 사용할 충분합니다!
다른 보조 범주는 많이 소개하지 않습니다. 인터넷에는 많은 리소스가 있으며 모두가 조합하여 배울 수 있기를 바랍니다.