一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java實現SSH模式加密

Java實現SSH模式加密

2020-03-21 12:05沉默王二 JAVA教程

這篇文章主要介紹了Java實現SSH模式加密的相關資料,需要的朋友可以參考下

Java實現SSH模式加密的實現原理思路分享給大家。

一、SSH加密原理

SSH是先通過非對稱加密告訴服務端一個對稱加密口令,然后進行驗證用戶名和密碼的時候,使用雙方已經知道的加密口令進行加密和解密,見下圖:

Java實現SSH模式加密

解釋:SSH中為什么要使用非對稱加密,又使用對稱加密,到底有什么用處?到底安全不安全?既然后來又使用了對稱加密,開始的時候為什么還要用非對稱加密?反過來,既然用非對稱加密,為什么又要使用對稱加密呢?

非對稱加密,是為了將客戶端產生的256位隨機的口令傳遞到服務端,那么在傳遞的過程中,使用公鑰進行了加密,這樣,這個256位的加密口令就很難被網絡上進行破解。
對稱加密,因為頻繁的使用非對稱加密是非常浪費性能的,那么SSH就是用了256位長度的口令作為接下來傳遞用戶名密碼時的加密口令,其破解的難度,想必大家都知道了,每一位上都有0-9種變化。
這樣安全嗎,我覺得還是很不錯的,具體使用起來也易于讓人理解。
二、我的SSH加密原理

①、使用場景

我所開發的項目是大宗期貨交易,主要服務于交易所,這也就產生一個需求就是,我們需要控制交易所使用我們軟件的周期。也就是說我們的項目留有一個后門,用來控制項目的周期,假如交易所使用軟件的周期到了,那么如果他不續費,而項目的代碼部署在人家的服務器上,此時我們就很難控制了,但是有了這個后門,到期后會自動停止軟件,這樣就不擔心交易所不給我們錢了。

②、使用方式

我們給交易的項目代碼中包含一個后門,該后門通過webservice client發送一個請求到web service。
web service接收到請求后,回給client需要的信息。
在以上這個過程當中,就會產生一個SSH加密的請求方式,請允許我用一個拙劣的圖表示一下。

Java實現SSH模式加密

三、我的SSH具體實現

既然要用到webservice,那么就需要建立web service服務,還有web service client。關于這方面,我暫時不想說太多,方式有很多,我在這就不誤導大家了。我是通過eclipse搞定的,可參照webservice之間通信 。

接下來,我將介紹代碼,但是考慮到篇幅問題,一些不必要的代碼我就不貼出來了,關鍵在于講解清楚這個原理。

①、service

ExchangeService.java

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public byte[] request(String param, String resultType) {
  logger.info("請求參數:" + param);
 
  // 返回對象
  KeyResult keyResult = new KeyResult();
 
  try {
    // 先獲取公鑰
    if (resultType.equals(PUBLIC_KEY_RESULT_TYPE)) {
 
      Map<String, Object> keyMap = RSACoder.initKey();
      // 產生公鑰和私鑰
      privateKey = RSACoder.getPrivateKey(keyMap);
 
      keyResult.setKey(RSACoder.getPublicKey(keyMap));
 
      logger.info("公鑰字符串:" + keyResult.getKey());
      logger.info("私鑰字符串:" + privateKey);
 
    } else if (resultType.equals(ECHOSTR_RESULT_TYPE)) {
 
      // 設置客戶端的口令信息
      byte[] paramByte = new BASE64Decoder().decodeBuffer(param);
      echoStr = new String(RSACoder.decryptByPrivateKey(paramByte, privateKey));
 
    } else {
      // 通過數據庫獲取交易所對應的權限信息.
      // 先將請求轉換為byte數組,然后再進行解密,最后轉換為字符串
      ExchangeInfo info = ExchangeInfo.dao.getInfoByName(new String(CryptUtil.decrypt(
          new BASE64Decoder().decodeBuffer(param), echoStr.getBytes())));
 
      String result = "";
 
      // 獲取系統啟用權限
      if (resultType.equals(PRIVILEGE_RESULT_TYPE)) {
        // 先判斷使用權限
 
        // 在判斷使用日期
        // 當前登錄用登錄時獲取登錄的當前日期和開始日期進行比較,然后計算還可以使用的日期
        long time = (new Date().getTime() / 1000) - string2DateInt(openday);
        // 換算成天數
        int day = (int) (time / (60 * 60 * 24));
        // 還可以使用的天數
        if (usedays - day > 0) {
          // 可以使用
          result = "1";
        } else {
          // 無法使用
          result = "0";
        }
 
      }
 
      keyResult.setResult(CryptUtil.encrypt(result.getBytes(), echoStr.getBytes()));
    }
 
    return JsonUtil.objectToByte(keyResult);
  } catch (Exception e) {
    logger.error("webservice出錯了!!!!");
    logger.error(e.getMessage(), e);
  }
 
  return null;
}

再贅述一下:

第一個判斷語句中的內容就是生成公鑰和私鑰,并且返回公鑰。
第二個判斷語句中的內容就是保存client發送的隨機字符串,這一步非常關鍵,隨機字符串首先通過公鑰進行了加密,這大大加強了加密的深度。
第三個判斷語句中的內容就是將client的權限通過隨機字符串進行加密。
②、client

ExchangeUtil.java

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public static boolean canRunForExchange(String resultType) {
  int i = 1;
  boolean result = false;
 
  while (true) {
    try {
      // webservice調用類
      ExchangeServiceProxy proxy = new ExchangeServiceProxy();
      BASE64Encoder encoder = new BASE64Encoder();
 
      // step1.獲取service產生的公鑰
      KeyResult keyResult = JsonUtil.byteToObject(proxy.request(null, PUBLIC_KEY_RESULT_TYPE),
          KeyResult.class);
 
      // step2.產生隨機字符串,發送到webserivce
      String echoStr = StrUtil.getEchoStrByLength(10);
      byte[] echoByteParam = RSACoder.encryptByPublicKey(echoStr.getBytes(), keyResult.getKey());
      proxy.request(encoder.encode(echoByteParam), ECHOSTR_RESULT_TYPE);
 
      // step3.加密客戶端請求信息,然后發送到webservice
      // 先加密為byte數組,然后轉換成字符串
      byte[] results = proxy.request(
          encoder.encode(CryptUtil.encrypt(Constants.client_type.getBytes(), echoStr.getBytes())),
          resultType);
      keyResult = JsonUtil.byteToObject(results, KeyResult.class);
 
      // step4.通過口令解密服務端返回消息
      String response = new String(CryptUtil.decrypt(keyResult.getResult(), echoStr.getBytes()));
      if (response.equals("1")) {
        result = true;
      }
      break;
    } catch (Exception e) {
      logger.debug("第" + i + "次加載webservice失敗");
      i++;
      logger.error(e.getMessage(), e);
 
      if (i >= 10) {
        break;
      }
    }
  }
 
  return result;
}

稍作解釋:

通過循環主要為了防止網絡斷開時服務不停的發送請求,最多10次就夠了。
主要有四步操作,注釋中我想解釋的還可以。
③、共享加密解密公共類

CryptUtil.java

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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;
 
public class CryptUtil {
  /**
  * @Title: encrypt
  * @Description: 加密
  * @param data
  * @param key
  * @return
  * @throws Exception
  */
  public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
    key = get8(key);
    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    DESKeySpec desKeySpec = new DESKeySpec(key);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
    IvParameterSpec iv = new IvParameterSpec(key);
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
    return cipher.doFinal(data);
  }
 
  /**
  * @Title: decrypt
  * @Description: 解密
  * @param data
  * @param key
  * @return
  * @throws Exception
  */
  public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
    key = get8(key);
    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    DESKeySpec desKeySpec = new DESKeySpec(key);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
    IvParameterSpec iv = new IvParameterSpec(key);
    cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
    return cipher.doFinal(data);
  }
 
  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)+"-";
    }
    return s;
  }
 
}

一般情況下,SHA和MD5兩種加密就夠我們使用了!
至于其他的輔助類我就不多介紹了,網上有很多資源,希望大家可以結合學習。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产欧美一区二区精品久久久 | 91porn最新地址 | 精品久久日日躁夜夜躁AV | 亚洲视频在线免费观看 | 免费观看在线永久免费xx视频 | 免费国产之a视频 | 日本免费不卡在线一区二区三区 | 特大黑人娇小亚洲女mp4 | 美日韩一区二区三区 | 99pao在线视频精品免费 | 关晓彤被调教出奶水的视频 | 窝窝午夜精品一区二区 | 99re这里只有精品在线观看 | 5151hh四虎国产精品 | 国产成人综合久久精品红 | 精品日韩二区三区精品视频 | 欧美人妖草草xxoo | 免费看视频网站 | 96萝莉| 韩国甜性涩爱免费观看 | 嗯啊在线观看免费影院 | 免费欧美日韩 | a∨在线观看 | 免费在线影院 | 91大神在线观看精品一区 | 日本老妇乱子伦中文视频 | 日韩高清在线高清免费 | 亚洲成色www久久网站 | 免费国产网站 | 欧美日韩精品在线观看 | 国内小情侣一二三区在线视频 | 日韩一级精品视频在线观看 | 日本一道本中文字幕 | 高h扶她文肉 | 精品视频免费在线观看 | 亚洲男人的天堂网 | 成人伊在线影院 | futa文| 免费看3d小舞被躁视频网站 | 精品国产自在现线拍国语 | 亚洲成综合人影院在院播放 |