Java笔记-加密应用在网络通信中的使用
生活随笔
收集整理的這篇文章主要介紹了
Java笔记-加密应用在网络通信中的使用
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
邏輯是這樣的:
?
邏輯解釋:
1.OpenSSL生成RSA私鑰和公鑰,公鑰存客戶端,私鑰存服務端;
2.客戶端與服務端的DH分別生成自己的公鑰和私鑰,并且使用相同的公鑰和私鑰算法;
3.首先客戶端把DH生成的公鑰使用RSA加密,通過HTTP協(xié)議,發(fā)送到服務端,服務端把先解密RSA,然后把自己DH模塊的公鑰發(fā)給客戶端;
4.客戶端和服務端都拿到了對方的公鑰,再與自己的私鑰,通過密鑰公式,算出AES加密密鑰。后面發(fā)送數(shù)據(jù)時都通過AES加密。
程序運行截圖如下:
?
關鍵源碼如下:
服務端(IDEA普通Java項目):
Main.java
package cn.it1995;import cn.it1995.http.HttpCallback; import cn.it1995.http.HttpServer; import cn.it1995.tool.AES; import cn.it1995.tool.DH; import cn.it1995.tool.DataSecret; import cn.it1995.tool.RSA;import java.io.UnsupportedEncodingException; import java.util.Map;public class Main {private static final String PUB_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjuN97tkBc0QcKGU9oXydaQN7q" +"wZnThxTOmdIc8O1yuA9FrDZpZ3Sz908vTqM/YPZkOUaYrGwsBO7FeQovoX7nQPKu" +"YQpRDqt7OKzhwPavyynH0Jz38PDyCBw45zwl4Ux8BtsggTrGVxAqNjO4KkuyL1QS" +"8amn4Fzl1CBre8Y0gQIDAQAB";private static final String PRI_KEY = "MIICdAIBADANBgkqhkiG9w0BAQEFAASCAl4wggJaAgEAAoGBAKO433u2QFzRBwoZ" +"T2hfJ1pA3urBmdOHFM6Z0hzw7XK4D0WsNmlndLP3Ty9Ooz9g9mQ5RpisbCwE7sV5" +"Ci+hfudA8q5hClEOq3s4rOHA9q/LKcfQnPfw8PIIHDjnPCXhTHwG2yCBOsZXECo2" +"M7gqS7IvVBLxqafgXOXUIGt7xjSBAgMBAAECgYAgp0uzcdsOaAY+ZmPnDitcHdoX" +"+jsC7EsjFZzJduf03G73V2yWwzKMfkPFzKpUhrM9tAq3gpQkh2tT6Vs1usEDbrDd" +"e08Cc3D5YWK7HuTfO3kkJTSNOK0JfuT1UQaTjCmDQWWjPmYbu6UN0UDv4Mo26dgl" +"cp9h0wlaPsSFN3O97QJBANgj+4i7ABAdbTuUfq6Tcr38E7wYSFTUeL5jTd4sO636" +"+KJ6zx4uTXAmxnt9OdIY1ihLRqDh8VbiorqOelGf6iMCQQDB6jZver3mTMe6ntSY" +"hx3JWOCDM3ULkPvOWGrAcRsNKjyIuo37taXa7fuqmVQQq9MJYikJfilMhkgwkV/X" +"ihcLAkBsOvBskj9A0ottJzmcT4dIbR6wtHQbzl078NwAIaQsxZyVN+vY0BTE0RXY" +"pmc6tmcevDr8uscv28Liqg/EKdCDAkAjL9C44djblUsYvgFtu/bXtlzm8ctnUeOf" +"ScP1L5DtDqD1XoStDAUQeOaVykTK0aL1rO4tXss3q5Yl2fs+LTyJAj8f7N5kzw08" +"9S5OWCHoEm5UOeAvjFh//cjXi6lyqetBW3w17muZ2OumUAbKJXksyzmT6/QRpkX3" +"S0w/tqdJXLs=";private static final String HANDHAKE = "handshake";public static void main(String[] args) throws UnsupportedEncodingException {// String content = "123456"; // String encrypted = RSA.encrypt(content, PUB_KEY); // System.out.println(encrypted); // System.out.println(RSA.decrypt(encrypted, PRI_KEY));//查密鑰 // DH dhC = new DH(); // DH dhS = new DH(); // // int publicKeyC = dhC.getPublicKey(); // int publicKeyS = dhS.getPublicKey(); // // byte[] secretC = dhC.getSecretKey(publicKeyS); // byte[] secretS = dhS.getSecretKey(publicKeyC); // // System.out.println("client's secrete is : "); // for(byte i : secretC){ // // System.out.print(i + " "); // } // System.out.println("\nserver's secrete is : "); // for(byte i : secretS){ // // System.out.print(i + " "); // }// AES aes = new AES(); // byte[] encrypted = aes.encrypt(content); // System.out.println(new String(encrypted)); // byte[] decrypt = aes.decrypt(encrypted); // System.out.println(new String(decrypt)); //System.out.println("start http server");HttpServer server = new HttpServer(new HttpCallback() {private DH mDh = new DH();private AES mAes = new AES();@Overridepublic byte[] onResponse(String request) {if(isHandshake(request)){//握手Map<String, String> header = HttpServer.getHeader(request);String handshake = header.get(HANDHAKE);System.out.println("Handshake為:" + handshake);int dhPubKey = Integer.valueOf(RSA.decrypt(handshake, PRI_KEY));//設置為AES密鑰mAes.setKey(mDh.getSecretKey(dhPubKey));System.out.println("解密后,客戶端dhPubKey:" + dhPubKey);return DataSecret.int2Byte(mDh.getPublicKey());}byte[] result = mAes.encrypt("Hello World");return result;}});server.startHttpServer();}private static boolean isHandshake(String request){return (request != null && request.contains(HANDHAKE));}}DH.java
package cn.it1995.tool;import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Random;public class DH {private static final int dhP = 45;private static final int dhG = 9;private int mPriKey;//構造函數(shù)隨機私鑰public DH(){Random r = new Random();mPriKey = r.nextInt(20);System.out.println("dh priKey is : " + mPriKey);}//公鑰計算公式計算出公鑰public int getPublicKey(){return (int) (Math.pow(dhG, mPriKey) % dhP);}//使用對方公鑰與自己私鑰生成密鑰//在把結果轉256字節(jié),AES密鑰需要128字節(jié)或256字節(jié)public byte[] getSecretKey(long publicKey){int buf = (int) (Math.pow(publicKey, mPriKey) % dhP);return sha256(buf);}//轉換成byte[256]類型,作為AES密鑰private byte[] sha256(int data){try {MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");messageDigest.update(DataSecret.int2Byte(data));return messageDigest.digest();}catch (NoSuchAlgorithmException e) {e.printStackTrace();}return new byte[]{-1};} }HttpServer.java
package cn.it1995.http;import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class HttpServer {private boolean mRunning;private HttpCallback mCallback;public HttpServer(HttpCallback Callback) {this.mCallback = Callback;}public void startHttpServer(){if(mRunning){return;}mRunning = true;try {ServerSocket serverSocket = new ServerSocket(80);while (mRunning){Socket accept = serverSocket.accept();ExecutorService threadPool = Executors.newCachedThreadPool();threadPool.execute(new HttpThread(accept, mCallback));}}catch (IOException e) {e.printStackTrace();}}public static Map<String, String> getHeader(String request){Map<String, String> header = new HashMap<>();BufferedReader reader = new BufferedReader(new StringReader(request));//逐行解析try{String line = reader.readLine();while (line != null && !line.trim().isEmpty()){int p = line.indexOf(":");if(p >= 0){header.put(line.substring(0, p).trim().toLowerCase(),line.substring(p + 1).trim());}line = reader.readLine();}}catch (Exception e){e.printStackTrace();}return header;} }HttpThread.java
package cn.it1995.http;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket;public class HttpThread implements Runnable{private Socket mSocket;private HttpCallback mCallback;public HttpThread(Socket socket, HttpCallback httpCallback){mSocket = socket;mCallback = httpCallback;}@Overridepublic void run() {try {BufferedReader reader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));String content;StringBuffer request = new StringBuffer();while((content = reader.readLine()) != null&& !content.trim().isEmpty()){request.append(content).append("\n");}System.out.println("request:\n" + request);byte[] response = new byte[0];if(mCallback != null){response = mCallback.onResponse(request.toString());}String responseFirstLine = "HTTP/1.1 200 OK \r\n";String responseHead = "Content-type:" + "text/html" + "\r\n";OutputStream outputStream = mSocket.getOutputStream();outputStream.write(responseFirstLine.getBytes());outputStream.write(responseHead.getBytes());outputStream.write("\r\n".getBytes());outputStream.write(response);mSocket.close();}catch (IOException e) {e.printStackTrace();}} }客戶端(Android項目):
MainActivity.java
package com.example.myclient;import android.os.Bundle;import com.example.myclient.http.HttpRequest; import com.example.myclient.tool.AES; import com.example.myclient.tool.DH; import com.example.myclient.tool.RSA; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar;import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar;import android.util.Log; import android.view.View; import android.view.Menu; import android.view.MenuItem;import java.io.IOException; import java.io.UnsupportedEncodingException;import okhttp3.Call; import okhttp3.Callback; import okhttp3.Response;public class MainActivity extends AppCompatActivity {private static final String PUB_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjuN97tkBc0QcKGU9oXydaQN7q" +"wZnThxTOmdIc8O1yuA9FrDZpZ3Sz908vTqM/YPZkOUaYrGwsBO7FeQovoX7nQPKu" +"YQpRDqt7OKzhwPavyynH0Jz38PDyCBw45zwl4Ux8BtsggTrGVxAqNjO4KkuyL1QS" +"8amn4Fzl1CBre8Y0gQIDAQAB";private static final String URL = "http://192.168.20.59/";private byte[] mAesKey;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Toolbar toolbar = findViewById(R.id.toolbar);setSupportActionBar(toolbar);FloatingActionButton fab = findViewById(R.id.fab);fab.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG).setAction("Action", null).show();}});final HttpRequest request = new HttpRequest(URL);findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if(mAesKey == null || mAesKey.length <= 0){final DH dh = new DH();int pubKey = dh.getPublicKey();Log.d("test", "dh 公鑰為:" + dh.getPublicKey());try {request.handshake(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {Log.d("error", "onFailure: 握手失敗");}@Overridepublic void onResponse(Call call, Response response) throws IOException {byte[] pubKey = response.body().bytes();mAesKey = dh.getSecretKey(pubKey);Log.d("success", "success: 握手成功aes密鑰為:" + new String(mAesKey));}}, RSA.encrypt(String.valueOf(pubKey), PUB_KEY));}catch (UnsupportedEncodingException e) {e.printStackTrace();}}else {request.request(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {Log.e("error", "請求失敗");}@Overridepublic void onResponse(Call call, Response response) throws IOException {byte[] bytes = response.body().bytes();AES aes = new AES(mAesKey);String content = new String(aes.decrypt(bytes));Log.e("success", "請求成功:" + content);}});}}});}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.menu_main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();//noinspection SimplifiableIfStatementif (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);} }源碼打包下載地址:
https://github.com/fengfanchen/Java/tree/master/AES%26RSA%26DHDemo
總結
以上是生活随笔為你收集整理的Java笔记-加密应用在网络通信中的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python笔记-XPath定位
- 下一篇: C++笔记-QSslSocket::su