SSHモード暗号化を実装するJavaの実装原則とアイデアは、お客様と共有されます。
1。SSH暗号化原理
SSHは、最初に非対称暗号化を介してサーバーの非対称暗号化パスワードを伝え、次に両当事者が暗号化と復号化についてすでに知っている暗号化パスワードを使用します。以下の図を参照してください。
説明:SSHで非対称暗号化と対称暗号化を使用する必要があるのはなぜですか?それの使用は何ですか?安全ですか?次に、対称暗号化を使用しましたが、なぜ最初に非対称暗号化を使用したのですか?一方、非対称暗号化が使用されるため、なぜ対称暗号化を使用する必要があるのですか?
非対称暗号化は、クライアントによって生成された256ビットのランダムパスワードをサーバーに渡すことです。その後、配信プロセス中に、公開キーが暗号化に使用されるため、この256ビットの暗号化されたパスワードをネットワークのクラックが困難になります。
対称暗号化は、非対称暗号化を頻繁に使用することはパフォーマンスの無駄であるため、SSHは256ビットの長さパスワードを次にユーザー名とパスワードを渡すときに暗号化されたパスワードとして使用します。誰もがひび割れの難しさを知っていると信じており、各ビットに0-9の変更があります。
これは安全ですか?私はそれがまだ非常に良いと思います、そして、それは使用するときに理解するのが簡単です。
2。私のSSH暗号化の原則
①、使用シナリオ
私が開発したプロジェクトは、主に取引所にサービスを提供するバルク先物取引です。これは、ソフトウェアを使用して交換のサイクルを制御する必要があるという要求を生み出します。言い換えれば、私たちのプロジェクトには、プロジェクトサイクルを制御するバックドアがあります。 Exchangeがソフトウェアサイクルを使用している場合、更新せず、プロジェクトコードが他の人のサーバーに展開されている場合、制御することは困難です。ただし、このバックドアを使用すると、ソフトウェアが期限切れになった後に自動的に停止するため、交換がお金を与えないことを心配する必要はありません。
②、使用方法
トランザクションに提供するプロジェクトコードには、Backdoorが含まれており、Webサービスクライアントを介してWebサービスにリクエストを送信します。
リクエストを受け取った後、Webサービスはクライアントが必要とする情報を返します。
上記のプロセスでは、SSH暗号化要求方法が生成されます。不器用な姿を使ってそれを表現させてください。
3。私のSSH実装
WebServiceを使用するため、WebサービスサービスとWebサービスクライアントを確立する必要があります。当面はこれについてあまり言いたくありません。多くの方法があるので、ここでみんなを誤解させることはありません。私はEclipseを通してそれをしました、そして、私はWebサービス間のコミュニケーションを参照することができます。
次に、コードを紹介しますが、長さの問題を考慮して、不要なコードをいくつか投稿しません。重要なのは、この原則を明確に説明することです。
①、サービス
ExchangeService.java
public byte [] request(string param、string resultType){logger.info( "要求パラメーター:" + param); // return object keyresult keyresult = new keyResult(); try {//最初に公開キーを取得するif(resultType.equals(public_key_result_type)){map <string、object> keymap = rsacoder.initkey(); // public and private Keys privatekey = rsacoder.getPrivateKey(keymap); keyresult.setkey(rsacoder.getPublickey(keymap)); logger.info( "public key string:" + 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 {//データベースを介して交換に対応する許可情報を取得します。 //最初にリクエストをバイト配列に変換し、次にそれを復号化し、最後にそれを文字列exchangeinfo info = exchangeinfo.getinfobyname(new string(cryptutil.decrypt()。デコードバッファー()。文字列結果= ""; //システムの有効化権限を取得するif(resultType.equals(privilege_result_type)){//使用権を最初に判断します。 //日int day =(int)(time /(60 * 60 * 24))に変換します。 //使用できる日数(使用 - day> 0){// result = "1"を使用できます。 } else {// result = "0"を使用できません; }} keyResult.setResult(cryptutil.encrypt(result.getBytes()、echostr.getBytes())); } jsonutil.objecttobyte(keyResult); } catch(Exception e){logger.error( "WebService Error !!!"); logger.error(e.getmessage()、e); } nullを返します;}詳しく説明してください:
最初の判断声明のコンテンツは、公開キーとプライベートキーを生成し、公開キーを返すことです。
2番目の判断ステートメントのコンテンツは、クライアントが送信したランダム文字列を保存することです。このステップは非常に重要です。ランダムな文字列は、最初に公開キーで暗号化され、暗号化の深さを大幅に向上させます。
3番目の判断ステートメントのコンテンツは、ランダムな文字列を介してクライアントのアクセス許可を暗号化することです。
②、クライアント
Exchangeutil.java
public static boolean canrunforexchange(string resultType){int i = 1; boolean result = false; while(true){try {// webservice calling class class exchangeServiceproxy proxy = new ExchangeServiceProxy(); base64Encoder encoder = new Base64Encoder(); // step1。サービスによって生成された公開キーを取得しますKeyResult keyResult = jsonutil.bytetOobject(proxy.request(null、public_key_result_type)、keyresult.class); //ステップ2。ランダムな文字列を生成し、webSerivce string echostr = strutil.getechostrbyLength(10)に送信します。 byte [] echobyteparam = rsacoder.encryptbypublickey(echostr.getBytes()、keyresult.getKey()); proxy.request(encoder.encode(echobyteparam)、echostr_result_type); // step3。クライアントリクエスト情報を暗号化し、WebService //最初の暗号化をバイト配列として送信し、string byte [] results = proxy.request(cryptutil.encrypt(constants.client_type.getbytes()、echostr.getbytes())、resulttpe)に変換します。 keyresult = jsonutil.bytetoobject(results、keyresult.class); //ステップ4。パスワードを介してメッセージを返しますdecryption server string = new String(cryptutil.decrypt(keyresult.getResult()、echostr.getBytes())); if(respons.equals( "1")){result = true; } 壊す; } catch(Exception e){logger.debug( "th" + i + "時間読み込みwebsvice failed"); i ++; logger.error(e.getmessage()、e); if(i> = 10){break; }}} return result;}簡単な説明:
ループは、主に、ネットワークが切断されたときにサービスが継続的にリクエストを送信するのを防ぎ、最大10倍で十分です。
4つの主な手順があり、コメントで説明したいことは大丈夫です。
in、公共クラスの共有暗号化と復号化
cryptutil.java
パッケージ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.ivparameterpec encrypt * @description:encrypt * @param data * @param key * @return * @throws例外 */ public static byte [] encrypt(byte [] data、byte [] key)throws {key = get8(key); cipher cipher = cipher.getInstance( "des/cbc/pkcs5padding"); deskeyspec deskeyspec = new deskeyspec(key); SecretKey KeyFactory = SecretKeyFactory.getInstance( "des"); SecretKey SecretKey = KeyFactory.GenerateSecret(deskeyspec); IVParameterSpec IV = new IVParameterSpec(key); cipher.init(cipher.encrypt_mode、secretkey、iv); cipher.dofinal(data)を返します。 } / ** * @title:decrypt * @description:decrypt * @param data * @param key * @return * / public static byte [] decrypt(byte [] data、byte [] key)throws {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); 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の暗号化は私たちが使用するのに十分です!
他の補助カテゴリについては、それらをあまり紹介しません。インターネットには多くのリソースがありますが、誰もが組み合わせて学ぶことができることを願っています。