之前项目总下面的加密都做过,但没总结感觉还是蒙的。
加密方式:
一.摘要加密 包括:MD5,CRC,SHA 等
对MD5比较熟悉简单原理:
1.将一个大数据,按照一定规则取出固定长度数据处理。
2.不可逆。
3.一般可以做校验比对。也有可能发生碰撞。
二.对称加密 包括:DES、3DES、AES、TDEA、Blowfifish、RC2、RC4、RC5、IDEA、SKIPJACK等。
通过密钥对数据做固定的位运算的的加密操作。
特点:数度快
三.非对称加密 包括:RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)
可以通过OpenSSL,生成公钥和私钥。
公钥给用户、私钥留给服务器自己;公钥进行加密,私钥解密。
典型应用: git用ssl方式下载代码,就需要将公钥放的git服务器
四.数字签名
这个之前一直没怎么理解透,我总结其实也是属于非对称加密的一种。
步骤:
1.用户先对数据MD5,得到结果用公钥加密得到数字签名。
2.将数据和数字签名一起发送给服务器
3.服务器用私钥对数字签名解码,得到MD5后的结果。
4.服务器将数据MD5,得到的结果和3步骤结果比对,如果一样就验证通过。
典型应用:https,https里面多了一个步骤CA。
下面为数字签名演示代码:测试复制的https://www.cnblogs.com/gaomanito/p/9569857.html
import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; /** * <p> * 封装同RSA非对称加密算法有关的方法,可用于数字签名,RSA加密解密 * </p> * * @Copyright:WDSsoft */ public class RSATest { public RSATest() { } /** * 使用私钥加密数据 * 用一个已打包成byte[]形式的私钥加密数据,即数字签名 * * @param keyInByte 打包成byte[]的私钥 * @param source 要签名的数据,一般应是数字摘要 * @return 签名 byte[] */ public static byte[] sign(byte[] keyInByte, byte[] source) { try { PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec(keyInByte); KeyFactory mykeyFactory = KeyFactory.getInstance("RSA"); PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec); Signature sig = Signature.getInstance("SHA1withRSA"); sig.initSign(privKey); sig.update(source); return sig.sign(); } catch (Exception e) { return null; } } /** * 验证数字签名 * * @param keyInByte 打包成byte[]形式的公钥 * @param source 原文的数字摘要 * @param sign 签名(对原文的数字摘要的签名) * @return 是否证实 boolean */ public static boolean verify(byte[] keyInByte, byte[] source, byte[] sign) { try { KeyFactory mykeyFactory = KeyFactory.getInstance("RSA"); Signature sig = Signature.getInstance("SHA1withRSA"); X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(keyInByte); PublicKey pubKey = mykeyFactory.generatePublic(pub_spec); sig.initVerify(pubKey); sig.update(source); return sig.verify(sign); } catch (Exception e) { return false; } } /** * 建立新的密钥对,返回打包的byte[]形式私钥和公钥 * * @return 包含打包成byte[]形式的私钥和公钥的object[], 其中,object[0]为私钥byte[],object[1]为公钥byte[] */ public static Object[] giveRSAKeyPairInByte() { KeyPair newKeyPair = creatmyKey(); if (newKeyPair == null) { return null; } Object[] re = new Object[2]; if (newKeyPair != null) { PrivateKey priv = newKeyPair.getPrivate(); byte[] b_priv = priv.getEncoded(); PublicKey pub = newKeyPair.getPublic(); byte[] b_pub = pub.getEncoded(); re[0] = b_priv; re[1] = b_pub; return re; } return null; } /** * 新建密钥对 * * @return KeyPair对象 */ public static KeyPair creatmyKey() { KeyPair myPair; long mySeed; mySeed = System.currentTimeMillis(); try { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); random.setSeed(mySeed); keyGen.initialize(1024, random); myPair = keyGen.generateKeyPair(); } catch (Exception e1) { return null; } return myPair; } /** * 使用RSA公钥加密数据 * * @param pubKeyInByte 打包的byte[]形式公钥 * @param data 要加密的数据 * @return 加密数据 */ public static byte[] encryptByRSA(byte[] pubKeyInByte, byte[] data) { try { KeyFactory mykeyFactory = KeyFactory.getInstance("RSA"); X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(pubKeyInByte); PublicKey pubKey = mykeyFactory.generatePublic(pub_spec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); return cipher.doFinal(data); } catch (Exception e) { return null; } } /** * 用RSA私钥解密 * * @param privKeyInByte 私钥打包成byte[]形式 * @param data 要解密的数据 * @return 解密数据 */ public static byte[] decryptByRSA(byte[] privKeyInByte, byte[] data) { try { PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec( privKeyInByte); KeyFactory mykeyFactory = KeyFactory.getInstance("RSA"); PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, privKey); return cipher.doFinal(data); } catch (Exception e) { return null; } } /** * 使用RSA私钥加密数据 * * @param privKeyInByte 打包的byte[]形式私钥 * @param data 要加密的数据 * @return 加密数据 */ public static byte[] encryptByRSA1(byte[] privKeyInByte, byte[] data) { try { PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec( privKeyInByte); KeyFactory mykeyFactory = KeyFactory.getInstance("RSA"); PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec); Cipher cipher = Cipher.getInstance(mykeyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privKey); return cipher.doFinal(data); } catch (Exception e) { return null; } } /** * 用RSA公钥解密 * * @param pubKeyInByte 公钥打包成byte[]形式 * @param data 要解密的数据 * @return 解密数据 */ public static byte[] decryptByRSA1(byte[] pubKeyInByte, byte[] data) { try { KeyFactory mykeyFactory = KeyFactory.getInstance("RSA"); X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(pubKeyInByte); PublicKey pubKey = mykeyFactory.generatePublic(pub_spec); Cipher cipher = Cipher.getInstance(mykeyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, pubKey); return cipher.doFinal(data); } catch (Exception e) { return null; } } /** * 计算字符串的SHA数字摘要,以byte[]形式返回 */ public static byte[] MdigestSHA(String source) { //byte[] nullreturn = { 0 }; try { MessageDigest thisMD = MessageDigest.getInstance("SHA"); byte[] digest = thisMD.digest(source.getBytes("UTF-8")); return digest; } catch (Exception e) { return null; } } /** * 测试 */ public static void main(String[] args) { try { //私钥加密 公钥解密 //生成私钥-公钥对 Object[] v = giveRSAKeyPairInByte(); //获得摘要 byte[] source = MdigestSHA("假设这是要加密的客户数据"); //使用私钥对摘要进行加密 获得密文 即数字签名 byte[] sign = sign((byte[]) v[0], source); //使用公钥对密文进行解密,解密后与摘要进行匹配 boolean yes = verify((byte[]) v[1], source, sign); if (yes) { System.out.println("匹配成功 合法的签名!"); } //公钥加密私钥解密 //获得摘要 byte[] sourcepub_pri = ("13265986584||316494646546486498||01||public").getBytes("UTF-8"); //使用公钥对摘要进行加密 获得密文 byte[] signpub_pri = encryptByRSA((byte[]) v[1], sourcepub_pri); //System.out.println("公钥加密密文:"+new String(Base64.encodeBase64(signpub_pri))); //使用私钥对密文进行解密 返回解密后的数据 byte[] newSourcepub_pri = decryptByRSA((byte[]) v[0], signpub_pri); System.out.println("私钥解密:" + new String(newSourcepub_pri, "UTF-8")); //对比源数据与解密后的数据 if (Arrays.equals(sourcepub_pri, newSourcepub_pri)) { System.out.println("匹配成功 合法的私钥!"); } //私钥加密公钥解密 //获得摘要 //byte[] sourcepri_pub = MdigestSHA("假设这是要加密的客户数据"); byte[] sourcepri_pub = ("13265986584||316494646546486498||01||private").getBytes("UTF-8"); //使用私钥对摘要进行加密 获得密文 byte[] signpri_pub = encryptByRSA1((byte[]) v[0], sourcepri_pub); // System.out.println("私钥加密密文:"+new String(Base64.encodeBase64(sign11))); //使用公钥对密文进行解密 返回解密后的数据 byte[] newSourcepri_pub = decryptByRSA1((byte[]) v[1], signpri_pub); System.out.println("公钥解密:" + new String(newSourcepri_pub, "UTF-8")); String PUBLICKEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCEGENnf3rdiO20isoLQqezw12FoWXII9FBw8nR1MWQ3X0CVzOsqY1hOmxD/YI9OB7WVIaVax5tj1l+wk6A0v85Z4OpGWqz4B5L3fCUlBwf/M6DXHlSN1OZttvQF3OeWvc6gvJHihR7pp18zc4KfCJx0Ry6IrGH/2SNOVE1AIgvRQIDAQAB"; String PRIVATEKEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIQYQ2d/et2I7bSKygtCp7PDXYWhZcgj0UHDydHUxZDdfQJXM6ypjWE6bEP9gj04HtZUhpVrHm2PWX7CToDS/zlng6kZarPgHkvd8JSUHB/8zoNceVI3U5m229AXc55a9zqC8keKFHumnXzNzgp8InHRHLoisYf/ZI05UTUAiC9FAgMBAAECgYAGNcHNds/G5G4QY8n1149cwx19b8YCL7Thu5ucUr1q/w6mcoUKY/oyjPWUCLH7wMyqVNTy51NJ4UhazjW0lrbK4ZbPDHFij9CiZ7QFASiQ/TQWaL+KSIWnE6/rK9IdouwFKxk+cvvLteZoAXP6mFcrsa7LzfkENiIMu7mjpTNHAQJBANXv9U5JWOAVhWHDQcEWKn7YKpAVRleXdeUeJrXcdkqBDI+P6suA9j+ahDREfu+x65wUsrJotPHUXgJG0TarJIUCQQCeEPLrv6Qvi5+nbn2Eifn/fjsmIdI0U2WZKDHWJEnLsRUuGDNYxVE/SPDNDedA2OHeFB6j0Kk/ECdsWnUq6zvBAkAgUGViFMwa1MVX1fFZo+p5TFdpef0s/9Cr8djxAULQ0BtAmAFkCa+oPcOYTXxK4jnvUmUHc69ZE7W7bEzvj/wtAkB50X4mClAzBFxK4XCC0QOG0HYtcStbgFpwqvWdn+Hvxc4Y9DW+WHPBXimXHvv2ki+gw8jJX2rQW1bGvwBFz30BAkASPkORJxVWv91StjI2f/HXDO5eG5/su/XIb3eajaLUSEdaQlcs3ywLrrJ0o3VAR0J9aq59cmp6em017AMnmbF7"; byte[] signPrivate = Base64.decodeBase64(PRIVATEKEY.getBytes()); byte[] signPublic = Base64.decodeBase64(PUBLICKEY.getBytes()); String publicpwd = "N/b4nYbbLFVq0yTAIOpNNydtNQUCQxQy0B7bD6kzxLMW2guYxXtWOC/9Z5dpWecx/y7d5CezUJ6cf/8++msiNie4DcKBaFDFPh5rPbjeEB+DRfhjcdR2BsVGXWLsq3dLYLgZObQXG6Tb9rXakuH34Y+6KIIwCjiODH2QAU+PSiM="; String privatepwd = "MTMyNjU5ODY1ODR8fDMxNjQ5NDY0NjU0NjQ4NjQ5OHx8MDF8fHByaXZhdGU="; //使用私钥对密文进行解密 返回解密后的数据 byte[] newSource111 = decryptByRSA(signPrivate, Base64.decodeBase64(publicpwd.getBytes())); System.out.println("私钥解密1:" + new String(newSource111, "UTF-8")); } catch (Exception e) { e.printStackTrace(); } /*运行结果: 匹配成功 合法的签名! 私钥解密:13265986584||316494646546486498||01||public 匹配成功 合法的私钥! 公钥解密:13265986584||316494646546486498||01||private 私钥解密1:13265986584||316494646546486498||01||3156464564*/ } }