常见加密算法
数字签名、信息加密 是前后端开发都经常需要使用到的技术,应用场景包括了用户登入、交易、信息通讯、oauth 等等,不同的应用场景也会需要使用到不同的签名加密算法,或者需要搭配不一样的 签名加密算法 来达到业务目标。这里简单的给大家介绍几种常见的签名加密算法和一些典型场景下的应用。
1-数字签名
数字签名,简单来说就是通过提供 可鉴别 的 数字信息 验证 自身身份 的一种方式。一套 数字签名 通常定义两种 互补 的运算,一个用于 签名,另一个用于 验证。分别由 发送者 持有能够 代表自己身份 的 私钥 (私钥不可泄露),由 接受者 持有与私钥对应的 公钥 ,能够在 接受 到来自发送者信息时用于 验证 其身份。
签名 最根本的用途是要能够唯一 证明发送方的身份,防止 中间人攻击、CSRF 跨域身份伪造。基于这一点在诸如 设备认证、用户认证、第三方认证 等认证体系中都会使用到 签名算法 (彼此的实现方式可能会有差异)。
2-加密和解密
2.1-加密
数据加密 的基本过程,就是对原来为 明文 的文件或数据按 某种算法 进行处理,使其成为 不可读 的一段代码,通常称为 “密文”。通过这样的途径,来达到 保护数据 不被 非法人窃取、阅读的目的。
2.2-解密
加密 的 逆过程 为 解密,即将该 编码信息 转化为其 原来数据 的过程。
3-加密算法的分类
加密算法分 对称加密 和 非对称加密,其中对称加密算法的加密与解密 密钥相同,非对称加密算法的加密密钥与解密 密钥不同,此外,还有一类 不需要密钥 的 散列算法。
常见的 对称加密 算法主要有 DES、3DES、AES 等,常见的 非对称算法 主要有 RSA、DSA 等,散列算法 主要有 SHA-1、MD5 等。
3.1-对称加密
对称加密算法 是应用较早的加密算法,又称为 共享密钥加密算法。在 对称加密算法 中,使用的密钥只有一个,发送 和 接收 双方都使用这个密钥对数据进行 加密 和 解密。这就要求加密和解密方事先都必须知道加密的密钥。
- 数据加密过程:在对称加密算法中,数据发送方 将 明文 (原始数据) 和 加密密钥 一起经过特殊 加密处理,生成复杂的 加密密文 进行发送。
- 数据解密过程:数据接收方 收到密文后,若想读取原数据,则需要使用 加密使用的密钥 及相同算法的 逆算法 对加密的密文进行解密,才能使其恢复成 可读明文。
3.2-非对称加密
非对称加密算法,又称为 公开密钥加密算法。它需要两个密钥,一个称为 公开密钥 (public key),即 公钥,另一个称为 私有密钥 (private key),即 私钥。
因为 加密 和 解密 使用的是两个不同的密钥,所以这种算法称为 非对称加密算法。
- 如果使用 公钥 对数据 进行加密,只有用对应的 私钥 才能 进行解密。
- 如果使用 私钥 对数据 进行加密,只有用对应的 公钥 才能 进行解密。
例子:甲方生成 一对密钥 并将其中的一把作为 公钥 向其它人公开,得到该公钥的 乙方 使用该密钥对机密信息 进行加密 后再发送给甲方,甲方再使用自己保存的另一把 专用密钥 (私钥),对 加密 后的信息 进行解密。
3.3-散列加密
单向散列加密算法常用于提取数据,验证数据的完整性。发送者将明文通过单向加密算法加密生成定长的密文串,然后将明文和密文串传递给接收方。接收方在收到报文后,将解明文使用相同的单向加密算法进行加密,得出加密后的密文串。随后与发送者发送过来的密文串进行对比,若发送前和发送后的密文串相一致,则说明传输过程中数据没有损坏;若不一致,说明传输过程中数据丢失了。其次也用于密码加密传递存储。单向加密算法只能用于对数据的加密,无法被解密,其特点为定长输出、雪崩效应。
3.4-各类加密算法对比
1. 散列加密算法
| 名称 | 安全性 | 速度 | 
|---|
| SHA-1 | 高 | 慢 | 
| MD5 | 中 | 快 | 
| SHA-256 | 更高 | 更慢 | 
2. 对称加密算法
| 名称 | 密钥名称 | 运行速度 | 安全性 | 资源消耗 | 
|---|
| DES | 56位 | 较快 | 低 | 中 | 
| 3DES | 112位或168位 | 慢 | 中 | 高 | 
| AES | 128、192、256位 | 快 | 高 | 低 | 
3. 非对称加密算法
| 名称 | 成熟度 | 安全性 | 运算速度 | 资源消耗 | 
|---|
| RSA | 高 | 高 | 中 | 中 | 
| ECC | 高 | 高 | 慢 | 高 | 
3.5-各类算法特点
1. 对称加密
- 特点:算法公开、它要求和接发送方收方在安全通信之前,商定一个秘钥,共同用这个秘钥进行加密和解密。
- 密钥管理:比较难,不适合互联网,一般用于内部系统
- 安全性:中
- 加密速度:快好 几个数量级 (软件加解密速度至少快 100倍,每秒可以加解密数M比特 数据),适合大数据量的加解密处
2. 非对称加密
- 特点:算法强度复杂
- 密钥管理:密钥容易管理
- 安全性:高
- 加密速度:比较慢,适合 小数据量 加解密或数据签名
3. 散列算法
- 特点:算法强度复杂
- 密钥管理:无秘钥
- 安全性:极高
- 加密速度:很慢
4-常见加密算法介绍
4.1-MD5加密算法
1. 介绍
MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被”压缩”成一种保密的格式 (也就是把一个任意长度的字节串变换成一定长的十六进制数字串)。
MD5加密算法用的是哈希函数,一般应用于对信息产生信息摘要,防止信息被篡改。最常见的使用是对密码加密、生成数字签名。从严格意义上来说,MD5是摘要算法,并非加密算法。MD5 生成密文时,无论要加密的字符串有多长,它都会输出长度为 128bits 的一个密文串,通常16 进制时为 32 个字符。
2. 特点
- 压缩性: 任意长度的数据,算出的MD5值长度都是固定的。
- 容易计算: 从原数据计算出MD5值很容易。
- 抗修改性: 对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
- 强抗碰撞: 已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
3. 代码实现
利用JDK提供java.security.MessageDigest类实现MD5算法:
| import java.security.MessageDigest;public class MD5Demo {
 
 public static void main(String[] args) {
 System.out.println(getMD5Code("你若安好,便是晴天"));
 }
 private MD5Demo() {
 }
 
 public static String getMD5Code(String message) {
 String md5Str = "";
 try {
 
 MessageDigest md = MessageDigest.getInstance("MD5");
 
 byte[] md5Bytes = md.digest(message.getBytes());
 md5Str = bytes2Hex(md5Bytes);
 }catch(Exception e) {
 e.printStackTrace();
 }
 return md5Str;
 }
 
 public static String bytes2Hex(byte[] bytes) {
 StringBuffer result = new StringBuffer();
 int temp;
 try {
 for (int i = 0; i < bytes.length; i++) {
 temp = bytes[i];
 if(temp < 0) {
 temp += 256;
 }
 if (temp < 16) {
 result.append("0");
 }
 result.append(Integer.toHexString(temp));
 }
 } catch (Exception e) {
 e.printStackTrace();
 }
 return result.toString();
 }
 }
 
 | 
结果:
| 6bab82679914f7cb480a120b532ffa80
 | 
注意MessageDigest类的几个方法:
| static MessageDigest getInstance(String algorithm)byte[] digest(byte[] input)
 
 | 
4.2-SHA1加密算法
SHA1加密算法,与MD5一样,也是目前较流行的摘要算法。但SHA1 比 MD5 的 安全性更高。对长度小于 2 ^ 64 位的消息,SHA1会产生一个 160 位的 消息摘要。基于 MD5、SHA1 的信息摘要特性以及不可逆,可以被应用在检查文件完整性, 数字签名等场景。
对于长度小于2^64位的消息,SHA1会产生一个160位(40个字符)的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。
SHA1有如下特性:
- 不可以从消息摘要中复原信息;
- 两个不同的消息不会产生同样的消息摘要,(但会有1x10 ^ 48分之一的机率出现相同的消息摘要,一般使用时忽略)。
| public static byte[] computeSHA1(byte[] content) {try {
 MessageDigest sha1 = MessageDigest.getInstance("SHA1");
 return sha1.digest(content);
 } catch (NoSuchAlgorithmException e) {
 throw new RuntimeException(e);
 }
 }
 
 | 
4.3-SHA256加密算法
SHA256是SHA2算法中的一种,如SHA2加密算法中有:SHA244、SHA256、SHA512等。SHA2属于SHA1的升级,SHA1是160位的哈希值,而SHA2是组合值,有不同的位数,其中最受欢迎的是256位(SHA256算法)。
SSL行业选择SHA作为数字签名的散列算法,从2011到2015,一直以SHA-1位主导算法。但随着互联网技术的提升,SHA-1的缺点越来越突显。从去年起,SHA-2成为了新的标准,所以现在签发的SSL证书,必须使用该算法签名。
| public static byte[] getSHA256(String str) {MessageDigest messageDigest;
 String encodestr = "";
 try {
 messageDigest = MessageDigest.getInstance("SHA-256");
 messageDigest.update(str.getBytes("UTF-8"));
 return messageDigest.digest());
 } catch (NoSuchAlgorithmException e) {
 e.printStackTrace();
 } catch (UnsupportedEncodingException e) {
 e.printStackTrace();
 }
 }
 
 | 
4.4-DES加密算法
DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,现在已经过时。
| 
 
 
 
 
 public class DesDemo {
 public DesDemo() {
 }
 
 public static void main(String args[]) {
 
 String str = "cryptology";
 
 String password = "95880288";
 byte[] result;
 try {
 result = DesDemo.encrypt(str.getBytes(), password);
 System.out.println("加密后:" + result);
 byte[] decryResult = DesDemo.decrypt(result, password);
 System.out.println("解密后:" + new String(decryResult));
 } catch (UnsupportedEncodingException e2) {
 
 e2.printStackTrace();
 } catch (Exception e1) {
 e1.printStackTrace();
 }
 }
 
 
 
 
 
 
 
 public static byte[] encrypt(byte[] datasource, String password) {
 try {
 SecureRandom random = new SecureRandom();
 DESKeySpec desKey = new DESKeySpec(password.getBytes());
 
 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
 SecretKey securekey = keyFactory.generateSecret(desKey);
 
 Cipher cipher = Cipher.getInstance("DES");
 
 cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
 
 
 return cipher.doFinal(datasource);
 
 } catch (Throwable e) {
 e.printStackTrace();
 }
 return null;
 }
 
 
 
 
 
 
 
 public static byte[] decrypt(byte[] src, String password) throws Exception {
 
 SecureRandom random = new SecureRandom();
 
 DESKeySpec desKey = new DESKeySpec(password.getBytes());
 
 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
 
 
 
 
 SecretKey securekey = keyFactory.generateSecret(desKey);
 
 Cipher cipher = Cipher.getInstance("DES");
 
 cipher.init(Cipher.DECRYPT_MODE, securekey, random);
 
 return cipher.doFinal(src);
 }
 }
 
 | 
结果:
| 加密后:[B@50cbc42f解密后:cryptology
 
 | 
4.5-3DES算法
3DES又称Triple DES,是DES加密算法的一种模式,它使用2条不同的56位的密钥对数据进行三次加密。DES使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。比起最初的DES,3DES更为安全。
| public class Des3 {private static final String Algorithm = "DESede";
 
 
 
 
 
 
 public static byte[] encryptMode(byte[] keybyte, byte[] src) {
 try {
 
 SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
 
 Cipher c1 = Cipher.getInstance(Algorithm);
 c1.init(Cipher.ENCRYPT_MODE, deskey);
 return c1.doFinal(src);
 } catch (java.security.NoSuchAlgorithmException e1) {
 e1.printStackTrace();
 } catch (javax.crypto.NoSuchPaddingException e2) {
 e2.printStackTrace();
 } catch (java.lang.Exception e3) {
 e3.printStackTrace();
 }
 return null;
 }
 
 
 
 
 
 
 
 public static byte[] decryptMode(byte[] keybyte, byte[] src) {
 try {
 
 SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
 
 Cipher c1 = Cipher.getInstance(Algorithm);
 c1.init(Cipher.DECRYPT_MODE, deskey);
 return c1.doFinal(src);
 } catch (Exception e) {
 e.printStackTrace();
 }
 return null;
 }
 
 public static String byte2hex(byte[] b) {
 String hs = "";
 String stmp = "";
 for (int n = 0; n < b.length; n++) {
 stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
 if (stmp.length() == 1) {
 hs = hs + "0" + stmp;
 } else {
 hs = hs + stmp;
 }
 if (n < b.length - 1) {
 hs = hs + ":";
 }
 }
 return hs.toUpperCase();
 }
 }
 
 | 
4.6-AES算法
AES算法是密码学中的高级加密标准,同时也是美国联邦政府采用的区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。算法采用对称分组密码体制,密钥长度的最少支持为 128 位、 192 位、256 位,分组长度 128 位,算法应易于各种硬件和软件实现。AES本身就是为了取代DES的,AES具有更好的安全性、效率和灵活性。
| public class AESUtils {
 
 
 
 
 
 
 
 public static byte[] encrypt(String content, String strKey) throws Exception {
 SecretKeySpec skeySpec = getKey(strKey);
 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
 IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());
 cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
 return cipher.doFinal(content.getBytes());
 }
 
 
 
 
 
 
 
 
 
 public static String decrypt(byte[] content, String strKey) throws Exception {
 SecretKeySpec skeySpec = getKey(strKey);
 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
 IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());
 cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
 byte[] original = cipher.doFinal(content);
 String originalString = new String(original);
 return originalString;
 }
 
 private static SecretKeySpec getKey(String strKey) throws Exception {
 byte[] arrBTmp = strKey.getBytes();
 byte[] arrB = new byte[16];
 for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
 arrB[i] = arrBTmp[i];
 }
 SecretKeySpec skeySpec = new SecretKeySpec(arrB, "AES");
 return skeySpec;
 }
 }
 
 | 
4.7-RSA加密算法
RSA是目前最有影响力和最常用的公钥加密算法。它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。
| 
 
 public class RSADemo {
 public static void main(String[] args) throws Exception {
 Map<String, Key> keyMap = initKey();
 String publicKey = getPublicKey(keyMap);
 String privateKey = getPrivateKey(keyMap);
 System.out.println(keyMap);
 System.out.println("-----------------------------------");
 System.out.println(publicKey);
 System.out.println("-----------------------------------");
 System.out.println(privateKey);
 System.out.println("-----------------------------------");
 byte[] encryptByPrivateKey = encryptByPrivateKey("123456".getBytes(), privateKey);
 byte[] encryptByPublicKey = encryptByPublicKey("123456", publicKey);
 System.out.println(encryptByPrivateKey);
 System.out.println("-----------------------------------");
 System.out.println(encryptByPublicKey);
 System.out.println("-----------------------------------");
 String sign = sign(encryptByPrivateKey, privateKey);
 System.out.println(sign);
 System.out.println("-----------------------------------");
 boolean verify = verify(encryptByPrivateKey, publicKey, sign);
 System.out.println(verify);
 System.out.println("-----------------------------------");
 byte[] decryptByPublicKey = decryptByPublicKey(encryptByPrivateKey, publicKey);
 byte[] decryptByPrivateKey = decryptByPrivateKey(encryptByPublicKey, privateKey);
 System.out.println(decryptByPublicKey);
 System.out.println("-----------------------------------");
 System.out.println(decryptByPrivateKey);
 }
 public static final String KEY_ALGORITHM = "RSA";
 public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
 private static final String PUBLIC_KEY = "RSAPublicKey";
 private static final String PRIVATE_KEY = "RSAPrivateKey";
 
 public static byte[] decryptBASE64(String key) {
 return Base64.decodeBase64(key);
 }
 
 public static String encryptBASE64(byte[] bytes) {
 return Base64.encodeBase64String(bytes);
 }
 
 
 
 
 
 
 
 
 public static String sign(byte[] data, String privateKey) throws Exception {
 
 byte[] keyBytes = decryptBASE64(privateKey);
 
 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
 
 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
 
 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
 
 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
 signature.initSign(priKey);
 signature.update(data);
 return encryptBASE64(signature.sign());
 }
 
 
 
 
 
 
 
 
 
 public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
 
 byte[] keyBytes = decryptBASE64(publicKey);
 
 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
 
 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
 
 PublicKey pubKey = keyFactory.generatePublic(keySpec);
 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
 signature.initVerify(pubKey);
 signature.update(data);
 
 return signature.verify(decryptBASE64(sign));
 }
 
 public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
 
 byte[] keyBytes = decryptBASE64(key);
 
 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
 Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
 
 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
 cipher.init(Cipher.DECRYPT_MODE, privateKey);
 return cipher.doFinal(data);
 }
 
 
 
 
 
 
 
 
 
 public static byte[] decryptByPrivateKey(String data, String key) throws Exception {
 return decryptByPrivateKey(decryptBASE64(data), key);
 }
 
 
 
 
 
 
 
 
 
 public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
 
 byte[] keyBytes = decryptBASE64(key);
 
 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
 Key publicKey = keyFactory.generatePublic(x509KeySpec);
 
 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
 cipher.init(Cipher.DECRYPT_MODE, publicKey);
 return cipher.doFinal(data);
 }
 
 
 
 
 
 
 
 
 
 public static byte[] encryptByPublicKey(String data, String key) throws Exception {
 
 byte[] keyBytes = decryptBASE64(key);
 
 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
 Key publicKey = keyFactory.generatePublic(x509KeySpec);
 
 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
 cipher.init(Cipher.ENCRYPT_MODE, publicKey);
 return cipher.doFinal(data.getBytes());
 }
 
 
 
 
 
 
 
 
 
 public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
 
 byte[] keyBytes = decryptBASE64(key);
 
 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
 Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
 
 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
 cipher.init(Cipher.ENCRYPT_MODE, privateKey);
 return cipher.doFinal(data);
 }
 
 
 
 
 
 
 
 public static String getPrivateKey(Map<String, Key> keyMap) throws Exception {
 Key key = (Key) keyMap.get(PRIVATE_KEY);
 return encryptBASE64(key.getEncoded());
 }
 
 
 
 
 
 
 
 public static String getPublicKey(Map<String, Key> keyMap) throws Exception {
 Key key = keyMap.get(PUBLIC_KEY);
 return encryptBASE64(key.getEncoded());
 }
 
 
 
 
 
 
 public static Map<String, Key> initKey() throws Exception {
 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
 keyPairGen.initialize(1024);
 KeyPair keyPair = keyPairGen.generateKeyPair();
 Map<String, Key> keyMap = new HashMap(2);
 keyMap.put(PUBLIC_KEY, keyPair.getPublic());
 
 keyMap.put(PRIVATE_KEY, keyPair.getPrivate());
 
 return keyMap;
 }
 }
 
 | 
结果:
| {RSAPublicKey=Sun RSA public key, 1024 bits  modulus:115328826086047873902606456571034976538836553998745367981848911677968062571831626674499650854318207280419960767020601253071739555161388135589487284843845439403614883967713749605268831336418001722701924537624573180276356615050309809260289965219855862692230362893996010057188170525719351126759886050891484226169
 public exponent: 65537, RSAPrivateKey=sun.security.rsa.RSAPrivateCrtKeyImpl@93479}
 -----------------------------------MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCkO9PBTOFJQTkzznALN62PU7ixd9YFjXrt2dPOGj3wwhymbOU8HLoCztjwpLXHgbpBUJlGmbURV955M1BkZ1kr5dkZYR5x1gO4xOnu8rEipy4AAMcpFttfiarIZrtzL9pKEvEOxABltVN4yzFDr3IjBqY46aHna7YjwhXI0xHieQIDAQAB
 -----------------------------------MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKQ708FM4UlBOTPOcAs3rY9TuLF31gWNeu3Z084aPfDCHKZs5TwcugLO2PCktceBukFQmUaZtRFX3nkzUGRnWSvl2RlhHnHWA7jE6e7ysSKnLgAAxykW21+Jqshmu3Mv2koS8Q7EAGW1U3jLMUOvciMGpjjpoedrtiPCFcjTEeJ5AgMBAAECgYAK4sxOa8IjEOexv2U92Rrv/SSo3sCY7Z/QVDft2V9xrewoO9+V9HF/7iYDDWffKYInAiimvVl7JM/iSLxza0ZFv29VMpyDcr4TigYmWwBlk7ZbxSTkqLdNwxxldMmEoTn1py53MUm+1V1K3rzNvJjuZaZFAevU7vUnwQwD+JGQYQJBAM9HBaC+dF3PJ2mkXekHpDS1ZPaSFdrdzd/GvHFi/cJAMM+Uz6PmpkosNXRtOpSYWwlOMRamLZtrHhfQoqSk3S8CQQDK1qL1jGvVdqw5OjqxktR7MmOsWUVZdWiBN+6ojxBgA0yVn0n7vkdAAgEZBj89WG0VHPEu3hd4AgXFZHDfXeDXAkBvSn7nE9t/Et7ihfI2UHgGJO8UxNMfNMB5Skebyb7eMYEDs67ZHdpjMOFypcMyTatzj5wjwQ3zyMvblZX+ONbZAkAX4ysRy9WvL+icXLUo0Gfhkk+WrnSyUldaUGH0y9Rb2kecn0OxN/lgGlxSvB+ac910zRHCOTl+Uo6nbmq0g3PFAkAyqA4eT7G9GXfncakgW1Kdkn72w/ODpozgfhTLNX0SGw1ITML3c4THTtH5h3zLi3AF9zJO2O+K6ajRbV0szHHI
 -----------------------------------
 [B@387c703b
 -----------------------------------
 [B@224aed64
 -----------------------------------la4Hc4n/UbeBu0z9iLRuwKVv014SiOJMXkO5qdJvKBsw0MlnsrM+89a3p73yMrb1dAnCU/2kgO0PtFpvmG8pzxTe1u/5nX/25iIyUXALlwVRptJyjzFE83g2IX0XEv/Dxqr1RCRcrMHOLQM0oBoxZCaChmyw1Ub4wsSs6Ndxb9M=
 -----------------------------------
 true
 -----------------------------------
 [B@c39f790
 -----------------------------------
 [B@71e7a66b
 
 | 
4.8-ECC算法
ECC(椭圆加密算法)是一种公钥加密体制,主要优势是在某些情况下它比其他的方法使用更小的密钥——比如RSA加密算法——提供相当的或更高等级的安全。不过一个缺点是加密和解密操作的实现比其他机制时间长。它相比RSA算法,对 CPU 消耗严重。
| public abstract class ECCCoder extends Coder {public static final String ALGORITHM = "EC";
 private static final String PUBLIC_KEY = "ECCPublicKey";
 private static final String PRIVATE_KEY = "ECCPrivateKey";
 
 
 
 
 
 
 
 
 public static byte[] decrypt(byte[] data, String key) throws Exception {
 
 byte[] keyBytes = decryptBASE64(key);
 
 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
 KeyFactory keyFactory = ECKeyFactory.INSTANCE;
 ECPrivateKey priKey = (ECPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
 ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(priKey.getS(),priKey.getParams());
 
 Cipher cipher = new NullCipher();
 cipher.init(Cipher.DECRYPT_MODE, priKey, ecPrivateKeySpec.getParams());
 return cipher.doFinal(data);
 }
 
 
 
 
 
 
 
 public static byte[] encrypt(byte[] data, String privateKey) throws Exception {
 
 byte[] keyBytes = decryptBASE64(privateKey);
 
 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
 KeyFactory keyFactory = ECKeyFactory.INSTANCE;
 ECPublicKey pubKey = (ECPublicKey) keyFactory.generatePublic(x509KeySpec);
 ECPublicKeySpec ecPublicKeySpec = new ECPublicKeySpec(pubKey.getW(), pubKey.getParams());
 Cipher cipher = new NullCipher();
 cipher.init(Cipher.ENCRYPT_MODE, pubKey, ecPublicKeySpec.getParams());
 return cipher.doFinal(data);
 }
 
 
 
 
 
 
 
 public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
 Key key = (Key) keyMap.get(PRIVATE_KEY);
 return encryptBASE64(key.getEncoded());
 }
 
 
 
 
 
 
 public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
 Key key = (Key) keyMap.get(PUBLIC_KEY);
 return encryptBASE64(key.getEncoded());
 }
 }
 
 | 
参考——
 ——