移動APP接口是怎么保證安全性的,可以采用https,或者是非對稱加密。
接口加密的目的是防止被別人用抓包工具,抓包后篡改數據。
關于加密算法常見的有對稱加密(DES)和非對稱加密(RSA)
對稱加密(DES):加密和解密用的是同一個密鑰
import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec;/*** DES加密介紹 DES是一種對稱加密算法,所謂對稱加密算法即:加密和解密使用相同密鑰的算法。DES加密算法出自IBM的研究,*/ public class DES {public DES() {}// 測試public static void main(String args[]) throws Exception {// 待加密內容String str = "irish";// 密碼,長度要是8的倍數 密鑰隨意定String password = "95881221";byte[] encrypt = encrypt(str.getBytes(), password);System.out.println("加密后:" + new String(encrypt));// 解密byte[] decrypt = decrypt(encrypt, password);System.out.println("解密后:" + new String(decrypt));}/*** 加密* * @param datasource byte[]* @param password String* @return byte[]*/public static byte[] encrypt(byte[] datasource, String password) {try {SecureRandom random = new SecureRandom();DESKeySpec desKey = new DESKeySpec(password.getBytes());// 創建一個密匙工廠,然后用它把DESKeySpec轉換成SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");SecretKey securekey = keyFactory.generateSecret(desKey);// Cipher對象實際完成加密操作Cipher cipher = Cipher.getInstance("DES");// 用密匙初始化Cipher對象,ENCRYPT_MODE用于將 Cipher 初始化為加密模式的常量 cipher.init(Cipher.ENCRYPT_MODE, securekey, random);// 現在,獲取數據并加密// 正式執行加密操作return cipher.doFinal(datasource); // 按單部分操作加密或解密數據,或者結束一個多部分操作} catch (Throwable e) {e.printStackTrace();}return null;}/*** 解密* * @param src byte[]* @param password String* @return byte[]* @throws Exception*/public static byte[] decrypt(byte[] src, String password) throws Exception {// DES算法要求有一個可信任的隨機數源SecureRandom random = new SecureRandom();// 創建一個DESKeySpec對象DESKeySpec desKey = new DESKeySpec(password.getBytes());// 創建一個密匙工廠SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 返回實現指定轉換的// 將DESKeySpec對象轉換成SecretKey對象SecretKey securekey = keyFactory.generateSecret(desKey);// Cipher對象實際完成解密操作Cipher cipher = Cipher.getInstance("DES");// 用密匙初始化Cipher對象 cipher.init(Cipher.DECRYPT_MODE, securekey, random);// 真正開始解密操作return cipher.doFinal(src);} }
?
非對稱加密RSA(RSA是他們的發明人的姓氏開頭字母拼在一起組成的)
采用第三方工具生成一對密鑰對(公鑰和私鑰)
加密方式分為兩種:
1如果用公鑰加密,必須采用私鑰解密
2如果用私鑰加密,必須采用公鑰解密
移動APP接口采用RSA加密的話,移動APP保存公鑰,服務器端保存私鑰
import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher;import org.apache.commons.codec.binary.Base64;/*** RSA加解密工具類* **/ public class RSAUtil {public static String publicKey; // 公鑰public static String privateKey; // 私鑰/*** 生成公鑰和私鑰*/public static void generateKey() {// 1.初始化秘鑰 KeyPairGenerator keyPairGenerator;try {keyPairGenerator = KeyPairGenerator.getInstance("RSA");SecureRandom sr = new SecureRandom(); // 隨機數生成器keyPairGenerator.initialize(512, sr); // 設置512位長的秘鑰KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 開始創建RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();// 進行轉碼publicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded());// 進行轉碼privateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded());} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch block e.printStackTrace();}}/*** 私鑰匙加密或解密* * @param content* @param privateKeyStr* @return*/public static String encryptByprivateKey(String content, String privateKeyStr, int opmode) {// 私鑰要用PKCS8進行處理PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr));KeyFactory keyFactory;PrivateKey privateKey;Cipher cipher;byte[] result;String text = null;try {keyFactory = KeyFactory.getInstance("RSA");// 還原Key對象privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);cipher = Cipher.getInstance("RSA");cipher.init(opmode, privateKey);if (opmode == Cipher.ENCRYPT_MODE) { // 加密result = cipher.doFinal(content.getBytes());text = Base64.encodeBase64String(result);} else if (opmode == Cipher.DECRYPT_MODE) { // 解密result = cipher.doFinal(Base64.decodeBase64(content));text = new String(result, "UTF-8");}} catch (Exception e) {// TODO Auto-generated catch block e.printStackTrace();}return text;}/*** 公鑰匙加密或解密* * @param content* @param privateKeyStr* @return*/public static String encryptByPublicKey(String content, String publicKeyStr, int opmode) {// 公鑰要用X509進行處理X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));KeyFactory keyFactory;PublicKey publicKey;Cipher cipher;byte[] result;String text = null;try {keyFactory = KeyFactory.getInstance("RSA");// 還原Key對象publicKey = keyFactory.generatePublic(x509EncodedKeySpec);cipher = Cipher.getInstance("RSA");cipher.init(opmode, publicKey);if (opmode == Cipher.ENCRYPT_MODE) { // 加密result = cipher.doFinal(content.getBytes());text = Base64.encodeBase64String(result);} else if (opmode == Cipher.DECRYPT_MODE) { // 解密result = cipher.doFinal(Base64.decodeBase64(content));text = new String(result, "UTF-8");}} catch (Exception e) {// TODO Auto-generated catch block e.printStackTrace();}return text;}public static void main(String[] args) {// 1. 生成(公鑰和私鑰)密鑰對 RSAUtil.generateKey();System.out.println("公鑰:" + RSAUtil.publicKey);System.out.println("私鑰:" + RSAUtil.privateKey);System.out.println("----------公鑰加密私鑰解密-------------");// 使用 公鑰加密,私鑰解密String textsr = "irish";String encryptByPublic = RSAUtil.encryptByPublicKey(textsr, RSAUtil.publicKey, Cipher.ENCRYPT_MODE);System.out.println("公鑰加密:" + encryptByPublic);String text = RSAUtil.encryptByprivateKey(encryptByPublic, RSAUtil.privateKey, Cipher.DECRYPT_MODE);System.out.print("私鑰解密:" + text);}}
?