国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java實現(xiàn)SSH模式加密

2019-11-26 14:41:42
字體:
供稿:網(wǎng)友

Java實現(xiàn)SSH模式加密的實現(xiàn)原理思路分享給大家。

一、SSH加密原理

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

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

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

①、使用場景

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

②、使用方式

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

三、我的SSH具體實現(xiàn)

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

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

①、service

ExchangeService.java

public byte[] request(String param, String resultType) {  logger.info("請求參數(shù):" + param);  // 返回對象  KeyResult keyResult = new KeyResult();  try {    // 先獲取公鑰    if (resultType.equals(PUBLIC_KEY_RESULT_TYPE)) {      Map<String, Object> keyMap = RSACoder.initKey();      // 產(chǎn)生公鑰和私鑰      privateKey = RSACoder.getPrivateKey(keyMap);      keyResult.setKey(RSACoder.getPublicKey(keyMap));      logger.info("公鑰字符串:" + keyResult.getKey());      logger.info("私鑰字符串:" + privateKey);    } else if (resultType.equals(ECHOSTR_RESULT_TYPE)) {      // 設(shè)置客戶端的口令信息      byte[] paramByte = new BASE64Decoder().decodeBuffer(param);      echoStr = new String(RSACoder.decryptByPrivateKey(paramByte, privateKey));    } else {      // 通過數(shù)據(jù)庫獲取交易所對應(yīng)的權(quán)限信息.      // 先將請求轉(zhuǎn)換為byte數(shù)組,然后再進行解密,最后轉(zhuǎn)換為字符串      ExchangeInfo info = ExchangeInfo.dao.getInfoByName(new String(CryptUtil.decrypt(          new BASE64Decoder().decodeBuffer(param), echoStr.getBytes())));      String result = "";      // 獲取系統(tǒng)啟用權(quán)限      if (resultType.equals(PRIVILEGE_RESULT_TYPE)) {        // 先判斷使用權(quán)限        // 在判斷使用日期        // 當(dāng)前登錄用登錄時獲取登錄的當(dāng)前日期和開始日期進行比較,然后計算還可以使用的日期        long time = (new Date().getTime() / 1000) - string2DateInt(openday);        // 換算成天數(shù)        int day = (int) (time / (60 * 60 * 24));        // 還可以使用的天數(shù)        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;}

再贅述一下:

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

ExchangeUtil.java

public static boolean canRunForExchange(String resultType) {  int i = 1;  boolean result = false;  while (true) {    try {      // webservice調(diào)用類      ExchangeServiceProxy proxy = new ExchangeServiceProxy();      BASE64Encoder encoder = new BASE64Encoder();      // step1.獲取service產(chǎn)生的公鑰      KeyResult keyResult = JsonUtil.byteToObject(proxy.request(null, PUBLIC_KEY_RESULT_TYPE),          KeyResult.class);      // step2.產(chǎn)生隨機字符串,發(fā)送到webserivce      String echoStr = StrUtil.getEchoStrByLength(10);      byte[] echoByteParam = RSACoder.encryptByPublicKey(echoStr.getBytes(), keyResult.getKey());      proxy.request(encoder.encode(echoByteParam), ECHOSTR_RESULT_TYPE);      // step3.加密客戶端請求信息,然后發(fā)送到webservice      // 先加密為byte數(shù)組,然后轉(zhuǎn)換成字符串      byte[] results = proxy.request(          encoder.encode(CryptUtil.encrypt(Constants.client_type.getBytes(), echoStr.getBytes())),          resultType);      keyResult = JsonUtil.byteToObject(results, KeyResult.class);      // step4.通過口令解密服務(wù)端返回消息      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;}

稍作解釋:

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

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;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兩種加密就夠我們使用了!
至于其他的輔助類我就不多介紹了,網(wǎng)上有很多資源,希望大家可以結(jié)合學(xué)習(xí)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 三门峡市| 岢岚县| 泸水县| 长海县| 本溪市| 平遥县| 镇远县| 崇左市| 南皮县| 柳林县| 铜梁县| 娄烦县| 龙井市| 中江县| 修武县| 甘孜| 弋阳县| 隆化县| 彰化市| 通化县| 瑞安市| 海原县| 潍坊市| 祥云县| 兴国县| 禄劝| 漳浦县| 合川市| 广州市| 贡觉县| 北辰区| 高阳县| 鄂伦春自治旗| 曲阳县| 崇礼县| 汝州市| 沙湾县| 通化县| 吉林省| 新野县| 灵石县|