編輯:關於Android編程
上篇博文中我們講了Java中的對稱加密,還沒有看過的童鞋可以打開鏈接查看對稱加密,今天我們重點講一下Java中的非對稱加密。
對於非對稱加密,它需要兩個密鑰來進行加密和解密,分別為公鑰和私鑰,其相對於對稱加密而言安全性更高;在Java中的非對稱加密算法主要有DH算法和RSA算法。
package com.example.asiatravel.learndes.dh_util; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; /** * Created by kuangxiaoguo on 16/9/14. * * DH加密工具類 */ public class DHUtil { public static final String PUBLIC_KEY = "DHPublicKey"; public static final String PRIVATE_KEY = "DHPrivateKey"; /** * 甲方初始化並返回密鑰 * * @return 甲方的公鑰和私鑰 * @throws Exception */ public static MapinitKey() throws Exception { //初始化密鑰對生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH"); keyPairGenerator.initialize(1024);// 默認是1024, 516-1024且是64的倍數 //生成密鑰對 KeyPair keyPair = keyPairGenerator.generateKeyPair(); //得到公鑰和私鑰 DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic(); DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate(); Map keyMap = new HashMap<>(); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** * 乙方根據甲方公鑰初始化並返回密鑰對 * * @param key 甲方的公鑰 * @return 乙方的公鑰和私鑰 * @throws Exception */ public static Map initKey(byte[] key) throws Exception { //將甲方公鑰從字節數組轉化為publicKey X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key); //實例化密鑰工廠 KeyFactory keyFactory = KeyFactory.getInstance("DH"); //產出甲方公鑰 DHPublicKey dhPublicKey = (DHPublicKey) keyFactory.generatePublic(keySpec); //剖析甲方公鑰獲取其參數 DHParameterSpec dhParameterSpec = dhPublicKey.getParams(); //實例化密鑰對生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH"); //用甲方公鑰初始化密鑰生成器 keyPairGenerator.initialize(dhParameterSpec); //獲取密鑰對 KeyPair keyPair = keyPairGenerator.generateKeyPair(); //獲取乙方公鑰和私鑰 DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic(); DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate(); //將乙方的公鑰和私鑰存入map集合中 Map keyMap = new HashMap<>(); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** * 根據對方的公鑰和自己的私鑰生成本地密鑰 * * @param publicKey 對方公鑰 * @param privateKey 自己私鑰 * @return 本地密鑰 * @throws Exception */ public static byte[] getSecretKey(byte[] publicKey, byte[] privateKey) throws Exception { //實例化密鑰工廠 KeyFactory keyFactory = KeyFactory.getInstance("DH"); //將公鑰從字節數組轉化為publicKey X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKey); PublicKey pubKey = keyFactory.generatePublic(publicKeySpec); //將私鑰從字節數組轉化為privateKey PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKey); PrivateKey priKey = keyFactory.generatePrivate(privateKeySpec); //根據以上公鑰和私鑰生成本地的密鑰secretKey //實例化keyAgreement KeyAgreement keyAgreement = KeyAgreement.getInstance("DH"); //用自己的私鑰初始化keyAgreement keyAgreement.init(priKey); //結合對方的公鑰進行運算 keyAgreement.doPhase(pubKey, true); //開始生成本地密鑰secretKey,密鑰算法為對稱加密算法 SecretKey secretKey = keyAgreement.generateSecret("AES");//DES 3DES AES return secretKey.getEncoded(); } /** * 從Map中獲取公鑰 * * @param keyMap 存放公鑰和密鑰的Map * @return 公鑰 */ public static byte[] getPublicKey(Map keyMap) { DHPublicKey key = (DHPublicKey) keyMap.get(PUBLIC_KEY); return key.getEncoded(); } /** * 從Map中獲取私鑰 * * @param keyMap 存放公鑰和密鑰的Map * @return 私鑰 */ public static byte[] getPrivateKey(Map keyMap) { DHPrivateKey key = (DHPrivateKey) keyMap.get(PRIVATE_KEY); return key.getEncoded(); } }
package com.example.asiatravel.learndes.rsa_util; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; /** * Created by kuangxiaoguo on 16/9/14. * * RAS加密工具類 */ public class RSAUtil { public static final String PUBLIC_KEY = "RSAPublicKey"; public static final String PRIVATE_KEY = "RSAPrivateKey"; /** * 生成RSA公鑰和私鑰 * * @return RSA公鑰和私鑰的Map集合 * @throws Exception */ public static MapinitKey() throws Exception { //初始化密鑰生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(1024); //獲取密鑰對 KeyPair keyPair = keyPairGenerator.generateKeyPair(); //獲取公鑰和私鑰 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); //把公鑰和私鑰存入map集合 Map keyMap = new HashMap<>(); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** * 使用公鑰加密 * * @param data 需要加密的數據 * @param publicKey 公鑰 * @return 加密後的字節數組 * @throws Exception */ public static byte[] encrypt(byte[] data, RSAPublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 使用私鑰解密 * * @param data 被公鑰加密後的數據 * @param privateKey 解密用的私鑰 * @return 解密後的數據的字節數組 * @throws Exception */ public static byte[] decrypt(byte[] data, RSAPrivateKey privateKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 從Map集合中獲取公鑰 * * @param keyMap 存儲公鑰和私鑰的map集合 * @return 返回公鑰 */ public static RSAPublicKey getPublicKey(Map keyMap) { return (RSAPublicKey) keyMap.get(PUBLIC_KEY); } /** * 從Map集合中獲取私鑰 * * @param keyMap 存儲公鑰和私鑰的map * @return 返回私鑰 */ public static RSAPrivateKey getPrivateKey(Map keyMap) { return (RSAPrivateKey) keyMap.get(PRIVATE_KEY); } }
package com.example.asiatravel.learndes; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import com.example.asiatravel.learndes.dh_util.DHUtil; import com.example.asiatravel.learndes.rsa_util.RSAUtil; import com.example.asiatravel.learndes.util.ByteToHexUtil; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.Map; public class MainActivity extends AppCompatActivity { private static final String DATA = "asiatravel"; private static final String TAG = "TAG"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); try { testDH(); } catch (Exception e) { Log.e(TAG, "onCreate: " + e.getMessage()); } try { testRSA(); } catch (Exception e) { Log.e(TAG, "onCreate: " + e.getMessage()); } } /** * 測試RSA加密-->非對稱加密 */ private void testRSA() throws Exception { Map總結:非對稱加密想對於對稱加密來講更加安全,其代碼邏輯方面相對於對稱加密來講也更為復雜,所以大家需要理解著去記憶,另外注釋我在代碼裡都寫上了,不明白的童鞋可以在下面留言。 最後,附上github源碼地址:點擊查看非對稱加密源碼,希望大家多多star!keyMap = RSAUtil.initKey(); RSAPublicKey publicKey = RSAUtil.getPublicKey(keyMap); RSAPrivateKey privateKey = RSAUtil.getPrivateKey(keyMap); System.out.println("RSA publicKey: " + publicKey); System.out.println("RSA privateKey: " + privateKey); //加密後的數據 byte[] encryptResult = RSAUtil.encrypt(DATA.getBytes(), publicKey); System.out.println(DATA + " RSA 加密: " + ByteToHexUtil.fromByteToHex(encryptResult)); //解密後的數據 byte[] decryptResult = RSAUtil.decrypt(encryptResult, privateKey); System.out.println(DATA + " RSA 解密: " + new String(decryptResult)); } /** * 測試DH加密-->非對稱加密 */ private void testDH() throws Exception { //甲方公鑰 byte[] publicKeyA; //甲方私鑰 byte[] privateKeyA; //甲方本地密鑰 byte[] secretKeyA; //乙方公鑰 byte[] publicKeyB; //乙方私鑰 byte[] privateKeyB; //乙方本地密鑰 byte[] secretKeyB; //初始化密鑰並生成甲方密鑰對 Map keyMapA = DHUtil.initKey(); publicKeyA = DHUtil.getPublicKey(keyMapA); privateKeyA = DHUtil.getPrivateKey(keyMapA); System.out.println("DH 甲方公鑰: " + ByteToHexUtil.fromByteToHex(publicKeyA)); System.out.println("DH 甲方私鑰: " + ByteToHexUtil.fromByteToHex(privateKeyA)); //乙方根據甲方公鑰生成乙方密鑰對 Map keyMapB = DHUtil.initKey(publicKeyA); publicKeyB = DHUtil.getPublicKey(keyMapB); privateKeyB = DHUtil.getPrivateKey(keyMapB); System.out.println("DH 乙方公鑰: " + ByteToHexUtil.fromByteToHex(publicKeyB)); System.out.println("DH 乙方私鑰: " + ByteToHexUtil.fromByteToHex(privateKeyB)); //對於甲方,根據乙方公鑰和自己的私鑰生成本地密鑰 secretKeyA secretKeyA = DHUtil.getSecretKey(publicKeyB, privateKeyA); //對於乙方,根據其甲公鑰和自己的私鑰生成本地密鑰 secretKeyB secretKeyB = DHUtil.getSecretKey(publicKeyA, privateKeyB); System.out.println("DH 甲方本地密鑰: " + ByteToHexUtil.fromByteToHex(secretKeyA)); System.out.println("DH 乙方本地密鑰: " + ByteToHexUtil.fromByteToHex(secretKeyB)); } }
我們先說一下思路,在android系統中就自帶了圖片剪切的應用,所以,我們只需要將我們獲取到的相片傳給圖片剪切應用,再將剪切好的相片返回到我們自己的界面顯示就ok了在開發
struct2 開發action 的三種方法1、繼承ActionSupportpublic class UserAction extends ActionSupport
本示例以Servlet為例,演示Android與Servlet的通信。眾所周知,Android與服務器通信通常采用HTTP通信方式和Socket通信方式,而HTTP通信方
01-11 19:47:57.153: A/libc(27675): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1),