移动APP接口安全性设计
移动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); } }