精华内容
下载资源
问答
  • JAVA各种加密与解密方式

    万次阅读 多人点赞 2019-08-30 15:59:43
    之前有兴趣研究了一下java的加密与解密的方法,发现市面上有好多种加密解密方式,在这里整理了一下。 目录 1.BASE64加密/解密 2.MD5(Message Digest Algorithm)加密/解密 3.DES(Data Encryption Standard)...

            之前有兴趣研究了一下java的加密与解密的方法,发现市面上有好多种加密解密方式,在这里整理了一下。

    目录

    1.BASE64加密/解密

     

    2.MD5(Message Digest Algorithm)加密

     

    3.DES(Data Encryption Standard)对称加密/解密

     

    4.AES(Advanced Encryption Standard) 加密/解密

     

    5.HMAC(Hash Message Authentication Code,散列消息鉴别码)

     

    6.恺撒加密

     

    7.SHA(Secure Hash Algorithm,安全散列算法)

     

    8.RSA 加密/解密

     

    9.PBE 加密/解密


     

    1.BASE64加密/解密

          Base64 编码是我们程序开发中经常使用到的编码方法,它用 64 个可打印字符来表示二进制数据。这 64 个字符是:小写字母 a-z、大写字母 A-Z、数字 0-9、符号"+"、"/"(再加上作为垫字的"=",实际上是 65 个字符),其他所有符号都转换成这个字符集中的字符。Base64 编码通常用作存储、传输一些二进制数据编码方法,所以说它本质上是一种将二进制数据转成文本数据的方案。

          通常用作对二进制数据进行加密,示例:

    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    public class Base64Util {
    
    	/***
    	 * BASE64解密
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] decryBASE64(String key) throws Exception{
    		return (new BASE64Decoder()).decodeBuffer(key);
    	}
    	
    	/***
    	 * BASE64加密
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static String encryptBASE64(byte[] key) throws Exception{
    		return (new BASE64Encoder()).encode(key);
    	}
    	
    }

     

    2.MD5(Message Digest Algorithm)加密

           MD5 是将任意长度的数据字符串转化成短小的固定长度的值的单向操作,任意两个字符串不应有相同的散列值。因此 MD5 经常用于校验字符串或者文件,因为如果文件的 MD5 不一样,说明文件内容也是不一样的,如果发现下载的文件和给定的 MD5 值不一样,就要慎重使用。

           MD5 主要用做数据一致性验证、数字签名和安全访问认证,而不是用作加密。比如说用户在某个网站注册账户时,输入的密码一般经过 MD5 编码,更安全的做法还会加一层盐(salt),这样密码就具有不可逆性。然后把编码后的密码存入数据库,下次登录的时候把密码 MD5 编码,然后和数据库中的作对比,这样就提升了用户账户的安全性。

        是一种单向加密算法,只能加密不能解密,示例:

    import java.security.MessageDigest;
    
    public class MD5Util {
    
    	public static final String KEY_MD5 = "MD5";  
    	
    	/***
    	 * MD5加密(生成唯一的MD5值)
    	 * @param data
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encryMD5(byte[] data) throws Exception {
    		MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
    		md5.update(data);
    		return md5.digest();
    	}
    	
    }
    

     

    3.DES(Data Encryption Standard)对称加密/解密

           DES 是一种对称加密算法,所谓对称加密算法就是:加密和解密使用相同密钥的算法。DES 加密算法出自 IBM 的研究,后来被美国政府正式采用,之后开始广泛流传。但近些年使用越来越少,因为 DES 使用 56 位密钥,以现代的计算能力,24 小时内即可被破解。

          顺便说一下 3DES(Triple DES),它是 DES 向 AES 过渡的加密算法,使用 3 条 56 位的密钥对数据进行三次加密。是 DES 的一个更安全的变形。它以 DES 为基本模块,通过组合分组方法设计出分组加密算法。比起最初的 DES,3DES 更为安全。

           使用 Java 实现 DES 加密解密,注意密码长度要是 8 的倍数。加密和解密的 Cipher 构造参数一定要相同,不然会报错。

           数据加密标准算法,和BASE64最明显的区别就是有一个工作密钥,该密钥既用于加密、也用于解密,并且要求密钥是一个长度至少大于8位的字符串,示例:

    import java.security.Key;
    import java.security.SecureRandom;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    
    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    public class DesUtil {
    
    	private static Key key;
    	
    	private static String KEY_STR="myKey";
    	private static String CHARSETNAME="UTF-8";
    	private static String ALGORITHM="DES";
    	
    	
    	static {
    		try {
    			//生成DES算法对象
    			KeyGenerator generator=KeyGenerator.getInstance(ALGORITHM);
    			//运用SHA1安全策略
    			SecureRandom secureRandom=SecureRandom.getInstance("SHA1PRNG");
    			//设置上密钥种子
    			secureRandom.setSeed(KEY_STR.getBytes());
    			//初始化基于SHA1的算法对象
    			generator.init(secureRandom);
    			//生成密钥对象
    			key=generator.generateKey();
    			generator=null;
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    	
    	
    	/***
    	 * 获取加密的信息
    	 * @param str
    	 * @return
    	 */
    	public static String getEncryptString(String str) {
    		//基于BASE64编码,接收byte[]并转换成String
    		BASE64Encoder encoder = new BASE64Encoder();
    		try {
    			//按utf8编码
    			byte[] bytes = str.getBytes(CHARSETNAME);
    			//获取加密对象
    			Cipher cipher = Cipher.getInstance(ALGORITHM);
    			//初始化密码信息
    			cipher.init(Cipher.ENCRYPT_MODE, key);
    			//加密
    			byte[] doFinal = cipher.doFinal(bytes);
    			//byte[]to encode好的String 并返回
    			return encoder.encode(doFinal);
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    	
    	
    	/***
    	 * 获取解密之后的信息
    	 * @param str
    	 * @return
    	 */
    	public static String getDecryptString(String str) {
    		BASE64Decoder decoder = new BASE64Decoder();
    		try {
    			//将字符串decode成byte[]
    			byte[] bytes = decoder.decodeBuffer(str);
    			//获取解密对象
    			Cipher cipher = Cipher.getInstance(ALGORITHM);
    			//初始化解密信息
    			cipher.init(Cipher.DECRYPT_MODE, key);
    			//解密
    			byte[] doFial = cipher.doFinal(bytes);
    			
    			return new String(doFial, CHARSETNAME);
    			
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    	
    }

     

    4.AES(Advanced Encryption Standard) 加密/解密

           高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称 Rijndael 加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES,已经被多方分析且广为全世界所使用。简单说就是 DES 的增强版,比 DES 的加密强度更高。

           AES 与 DES 一样,一共有四种加密模式:电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)。关于加密模式的介绍,推荐这篇文章:高级加密标准AES的工作模式(ECB、CBC、CFB、OFB)

    示例代码:

    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    public class AESUtil {
    
    	public static final String algorithm = "AES";
    	// AES/CBC/NOPaddin
    	// AES 默认模式
    	// 使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new
    	// IvParameterSpec(key.getBytes());
    	// NOPadding: 使用NOPadding模式时, 原文长度必须是8byte的整数倍
    	public static final String transformation = "AES/CBC/NOPadding";
    	public static final String key = "1234567812345678";
    
    	/***
    	 * 加密
    	 * @param original 需要加密的参数(注意必须是16位)
    	 * @return
    	 * @throws Exception
    	 */
    	public static String encryptByAES(String original) throws Exception {
    		// 获取Cipher
    		Cipher cipher = Cipher.getInstance(transformation);
    		// 生成密钥
    		SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
    		// 指定模式(加密)和密钥
    		// 创建初始化向量
    		IvParameterSpec iv = new IvParameterSpec(key.getBytes());
    		cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
    		// cipher.init(Cipher.ENCRYPT_MODE, keySpec);
    		// 加密
    		byte[] bytes = cipher.doFinal(original.getBytes());
    
    		return Base64Util.encryptBASE64(bytes);
    	}
    
    	/**
    	 * 解密
    	 * @param encrypted 需要解密的参数
    	 * @return
    	 * @throws Exception
    	 */
    	public static String decryptByAES(String encrypted) throws Exception {
    		// 获取Cipher
    		Cipher cipher = Cipher.getInstance(transformation);
    		// 生成密钥
    		SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
    		// 指定模式(解密)和密钥
    		// 创建初始化向量
    		IvParameterSpec iv = new IvParameterSpec(key.getBytes());
    		cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
    		// cipher.init(Cipher.DECRYPT_MODE, keySpec);
    		// 解密
    		byte[] bytes = cipher.doFinal(Base64Util.decryBASE64(encrypted));
    
    		return new String(bytes);
    	}
    
    }

     

    5.HMAC(Hash Message Authentication Code,散列消息鉴别码)

           使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证,示例:

    import javax.crypto.KeyGenerator;
    import javax.crypto.Mac;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    public class HMACUtil {
    
    	public static final String KEY_MAC = "HmacMD5";  
    	
    	/***
    	 * 初始化HMAC密钥
    	 * @return
    	 * @throws Exception
    	 */
    	public static String initMacKey() throws Exception{
    		
    		KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
    		SecretKey secreKey = keyGenerator.generateKey();
    		return Base64Util.encryptBASE64(secreKey.getEncoded());
    	}
    	
    	/**
    	 * HMAC加密
    	 * @param data
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encryHMAC(byte[] data, String key) throws Exception{
    		SecretKey secreKey = new SecretKeySpec(Base64Util.decryBASE64(key), KEY_MAC);
    		Mac mac = Mac.getInstance(secreKey.getAlgorithm());
    		mac.init(secreKey);
    		return mac.doFinal();
    	}
    	
    }

     

    6.恺撒加密

    • 在密码学中,恺撒密码是一种最简单并且最广为人知的加密技术。

    • 它是一种替换加密的技术,明文中的所欲字母都在字母表上向后(或向前)按照一个固定的数目进行偏移后被替换成密文。

    • 例如:当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推。

    • 这个加密方法是以恺撒的名字命名的,当年恺撒曾用此方法与其将军们进行联系。

    • 恺撒密码通常被座位其他更复杂的加密方法中的一个步骤。

    示例代码:

    public class KaisaUtil {
    
    	/***
    	 * 使用凯撒加密方式加密数据
    	 * @param orignal 原文
    	 * @param key 密钥
    	 * @return 加密后的字符
    	 */
    	private static String encryptKaisa(String orignal, int key) {
    		//将字符串转换为数组
    		char[] chars = orignal.toCharArray();
    		StringBuffer buffer = new StringBuffer();
    		//遍历数组
    		for(char aChar : chars) {
    			//获取字符的ASCII编码
    			int asciiCode = aChar;
    			//偏移数据
    			asciiCode += key;
    			//将偏移后的数据转为字符
    			char result = (char)asciiCode;
    			//拼接数据
    			buffer.append(result);
    		}
    		return buffer.toString();
    	}
    	
    	/**
    	 * 使用凯撒加密方式解密数据
    	 *
    	 * @param encryptedData :密文
    	 * @param key           :密钥
    	 * @return : 源数据
    	 */
    	private static String decryptKaiser(String encryptedData, int key) {
    	    // 将字符串转为字符数组
    	    char[] chars = encryptedData.toCharArray();
    	    StringBuilder sb = new StringBuilder();
    	    // 遍历数组
    	    for (char aChar : chars) {
    	        // 获取字符的ASCII编码
    	        int asciiCode = aChar;
    	        // 偏移数据
    	        asciiCode -= key;
    	        // 将偏移后的数据转为字符
    	        char result = (char) asciiCode;
    	        // 拼接数据
    	        sb.append(result);
    	    }
    
    	    return sb.toString();
    	}
    	
    	
    	public static void main(String[] args) {
    		String str = "open fire";
    		String encode = encryptKaisa(str, 3);
    		System.out.println("加密后:"+encode);
    		
    		String decode = decryptKaiser(encode, 3);
    		System.out.println("解密后:"+decode);
    		
    	}
    	
    }

     

    7.SHA(Secure Hash Algorithm,安全散列算法)

            SHA全名叫做安全散列算法,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。

            数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域,示例:

    import java.security.MessageDigest;
    
    public class SHAUtil {
    
    	public static final String KEY_SHA = "SHA";  
        public static final String ALGORITHM = "SHA-256";
    	
    	/***
    	 * SHA加密(比MD5更安全)
    	 * @param data
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encryptSHA(byte[] data) throws Exception{
    		MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
    		sha.update(data);
    		return sha.digest();
    	}
    	
    	
    	public static String SHAEncrypt(final String content) {
            try {
                MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
                byte[] sha_byte = sha.digest(content.getBytes());
                StringBuffer hexValue = new StringBuffer();
                for (byte b : sha_byte) {
                    //将其中的每个字节转成十六进制字符串:byte类型的数据最高位是符号位,通过和0xff进行与操作,转换为int类型的正整数。
                    String toHexString = Integer.toHexString(b & 0xff);
                    hexValue.append(toHexString.length() == 1 ? "0" + toHexString : toHexString);
                }
                return hexValue.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
           return "";
        }
    
    
        
        //SHA-256加密
        public static String SHA256Encrypt(String sourceStr) {
            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance(ALGORITHM);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            if (null != md) {
                md.update(sourceStr.getBytes());
                String digestStr = getDigestStr(md.digest());
                return digestStr;
            }
    
            return null;
        }
    
        private static String getDigestStr(byte[] origBytes) {
            String tempStr = null;
            StringBuilder stb = new StringBuilder();
            for (int i = 0; i < origBytes.length; i++) {
                tempStr = Integer.toHexString(origBytes[i] & 0xff);
                if (tempStr.length() == 1) {
                    stb.append("0");
                }
                stb.append(tempStr);
    
            }
            return stb.toString();
        }
    }

     

    8.RSA 加密/解密

           RSA算法是一种非对称加密算法,所谓非对称就是该算法需要一对密钥,若使用其中一个加密,则需要用另一个才能解密。目前它是最有影响力和最常用的公钥加密算法,能够抵抗已知的绝大多数密码攻击。从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。

           该算法基于一个的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。由于进行的都是大数计算,RSA 最快的情况也比 DES 慢上好几倍,比对应同样安全级别的对称密码算法要慢 1000 倍左右。所以 RSA 一般只用于少量数据加密,比如说交换对称加密的密钥。

    使用 RSA 加密主要有这么几步:生成密钥对、公开公钥、公钥加密私钥解密、私钥加密公钥解密。

    示例代码:

    import com.sun.org.apache.xml.internal.security.utils.Base64;
    import javax.crypto.Cipher;
    
    import org.apache.commons.io.FileUtils;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.nio.charset.Charset;
    import java.security.*;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    public class RsaUtil {
    
    	/**
         * 生成密钥对并保存在本地文件中
         *
         * @param algorithm : 算法
         * @param pubPath   : 公钥保存路径
         * @param priPath   : 私钥保存路径
         * @throws Exception
         */
        private static void generateKeyToFile(String algorithm, String pubPath, String priPath) throws Exception {
            // 获取密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
            // 获取密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            // 获取公钥
            PublicKey publicKey = keyPair.getPublic();
            // 获取私钥
            PrivateKey privateKey = keyPair.getPrivate();
            // 获取byte数组
            byte[] publicKeyEncoded = publicKey.getEncoded();
            byte[] privateKeyEncoded = privateKey.getEncoded();
            // 进行Base64编码
            String publicKeyString = Base64.encode(publicKeyEncoded);
            String privateKeyString = Base64.encode(privateKeyEncoded);
            // 保存文件
            FileUtils.writeStringToFile(new File(pubPath), publicKeyString, Charset.forName("UTF-8"));
            FileUtils.writeStringToFile(new File(priPath), privateKeyString, Charset.forName("UTF-8"));
    
        }
    
        /**
         * 从文件中加载公钥
         *
         * @param algorithm : 算法
         * @param filePath  : 文件路径
         * @return : 公钥
         * @throws Exception
         */
        private static PublicKey loadPublicKeyFromFile(String algorithm, String filePath) throws Exception {
            // 将文件内容转为字符串
            String keyString = FileUtils.readFileToString(new File(filePath), Charset.forName("UTF-8"));
    
            return loadPublicKeyFromString(algorithm, keyString);
    
        }
    
        /**
         * 从字符串中加载公钥
         *
         * @param algorithm : 算法
         * @param keyString : 公钥字符串
         * @return : 公钥
         * @throws Exception
         */
        private static PublicKey loadPublicKeyFromString(String algorithm, String keyString) throws Exception {
            // 进行Base64解码
            byte[] decode = Base64.decode(keyString);
            // 获取密钥工厂
            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
            // 构建密钥规范
            X509EncodedKeySpec keyspec = new X509EncodedKeySpec(decode);
            // 获取公钥
            return keyFactory.generatePublic(keyspec);
    
        }
    
        /**
         * 从文件中加载私钥
         *
         * @param algorithm : 算法
         * @param filePath  : 文件路径
         * @return : 私钥
         * @throws Exception
         */
        private static PrivateKey loadPrivateKeyFromFile(String algorithm, String filePath) throws Exception {
            // 将文件内容转为字符串
            String keyString = FileUtils.readFileToString(new File(filePath), Charset.forName("UTF-8"));
            return loadPrivateKeyFromString(algorithm, keyString);
    
        }
    
        /**
         * 从字符串中加载私钥
         *
         * @param algorithm : 算法
         * @param keyString : 私钥字符串
         * @return : 私钥
         * @throws Exception
         */
        private static PrivateKey loadPrivateKeyFromString(String algorithm, String keyString) throws Exception {
            // 进行Base64解码
            byte[] decode = Base64.decode(keyString);
            // 获取密钥工厂
            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
            // 构建密钥规范
            PKCS8EncodedKeySpec keyspec = new PKCS8EncodedKeySpec(decode);
            // 生成私钥
            return keyFactory.generatePrivate(keyspec);
    
        }
    
        /**
         * 使用密钥加密数据
         *
         * @param algorithm      : 算法
         * @param input          : 原文
         * @param key            : 密钥
         * @param maxEncryptSize : 最大加密长度(需要根据实际情况进行调整)
         * @return : 密文
         * @throws Exception
         */
        private static String encrypt(String algorithm, String input, Key key, int maxEncryptSize) throws Exception {
            // 获取Cipher对象
            Cipher cipher = Cipher.getInstance(algorithm);
            // 初始化模式(加密)和密钥
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // 将原文转为byte数组
            byte[] data = input.getBytes();
            // 总数据长度
            int total = data.length;
            // 输出流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            decodeByte(maxEncryptSize, cipher, data, total, baos);
            // 对密文进行Base64编码
            return Base64.encode(baos.toByteArray());
    
        }
    
        /**
         * 解密数据
         *
         * @param algorithm      : 算法
         * @param encrypted      : 密文
         * @param key            : 密钥
         * @param maxDecryptSize : 最大解密长度(需要根据实际情况进行调整)
         * @return : 原文
         * @throws Exception
         */
        private static String decrypt(String algorithm, String encrypted, Key key, int maxDecryptSize) throws Exception {
            // 获取Cipher对象
            Cipher cipher = Cipher.getInstance(algorithm);
            // 初始化模式(解密)和密钥
            cipher.init(Cipher.DECRYPT_MODE, key);
            // 由于密文进行了Base64编码, 在这里需要进行解码
            byte[] data = Base64.decode(encrypted);
            // 总数据长度
            int total = data.length;
            // 输出流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
            decodeByte(maxDecryptSize, cipher, data, total, baos);
            // 输出原文
            return baos.toString();
    
        }
    
        /**
         * 分段处理数据
         *
         * @param maxSize : 最大处理能力
         * @param cipher  : Cipher对象
         * @param data    : 要处理的byte数组
         * @param total   : 总数据长度
         * @param baos    : 输出流
         * @throws Exception
         */
        private static void decodeByte(int maxSize, Cipher cipher, byte[] data, int total, ByteArrayOutputStream baos) throws Exception {
            // 偏移量
            int offset = 0;
            // 缓冲区
            byte[] buffer;
            // 如果数据没有处理完, 就一直继续
            while (total - offset > 0) {
                // 如果剩余的数据 >= 最大处理能力, 就按照最大处理能力来加密数据
                if (total - offset >= maxSize) {
                    // 加密数据
                    buffer = cipher.doFinal(data, offset, maxSize);
                    // 偏移量向右侧偏移最大数据能力个
                    offset += maxSize;
                } else {
                    // 如果剩余的数据 < 最大处理能力, 就按照剩余的个数来加密数据
                    buffer = cipher.doFinal(data, offset, total - offset);
                    // 偏移量设置为总数据长度, 这样可以跳出循环
                    offset = total;
                }
                // 向输出流写入数据
                baos.write(buffer);
            }
        }
    }

      加密算法的安全级别(Security Level of Cryptographic Algorithms):

    安全级别 
    (Security Level)
    工作因素 
    (Work Factor)
    算法 
    (Algorithms)
    薄弱(Weak)O(240)DESMD5
    传统(Legacy)O(264)RC4SHA-1
    基准(Baseline)O(280)3DES
    标准(Standard)O(2128)AES-128SHA-256
    较高(High)O(2192)AES-192SHA-384
    超高(Ultra)O(2256)AES-256SHA-512

     

    9.PBE 加密/解密

         PBE是一种基于口令的加密算法,使用口令代替其他对称加密算法中的密钥,其特点在于口令由用户自己掌管,不借助任何物理媒体;采用随机数(这里我们叫做盐)杂凑多重加密等方法保证数据的安全性。

         PBE算法是对称加密算法的综合算法,常见算法PBEWithMD5AndDES,使用MD5和DES算法构建了PBE算法。将盐附加在口令上,通过消息摘要算法经过迭代获得构建密钥的基本材料,构建密钥后使用对称加密算法进行加密解密。

    算法/密钥长度/默认密钥长度:

    1.PBEWithMD5AndDES/56/56
    2.PBEWithMD5AndTripleDES/112,168/168
    3.PBEWithSHA1AndDESede/112,168/168
    4.PBEWithSHA1AndRC2_40/40 to 1024/128

    工作模式:CBC
    填充方式:PKCS5Padding

    示例代码:

    import java.security.Key;
    import java.security.SecureRandom;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.PBEKeySpec;
    import javax.crypto.spec.PBEParameterSpec;
    
    public class PBEUtil {
    
    	public static final String ALGORITHM = "PBEWITHMD5andDES";
    	
    	public static final int ITERATION_COUNT = 100;
    	
    	
    	public static byte[] initSalt() throws Exception{
    		//实例化安全随机数
    		SecureRandom random = new SecureRandom();
    		return random.generateSeed(8);
    	}
    	
    	/***
    	 * 转换密钥
    	 * @param password 密码
    	 * @return 密钥
    	 * @throws Exception
    	 */
    	private static Key toKey(String password) throws Exception{
    		//密钥材料
    		PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
    		//实例化
    		SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
    		//生成密钥
    		return factory.generateSecret(keySpec);
    	}
    	
    	/***
    	 * 加密
    	 * @param data 待加密数据
    	 * @param password 密钥
    	 * @param salt
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encrypt(byte[] data, String password, byte[] salt) throws Exception{
    		//转换密钥
    		Key key = toKey(password);
    		//实例化PBE参数材料
    		PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);
    		//实例化
    		Cipher cipher = Cipher.getInstance(ALGORITHM);
    		//初始化
    		cipher.init(Cipher.ENCRYPT_MODE, key, spec);
    		return cipher.doFinal(data);
    	}
    	
    	
    	/***
    	 * 解密
    	 * @param data 待解密数据
    	 * @param password 密钥
    	 * @param salt
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] decrypt(byte[] data, String password, byte[] salt) throws Exception{
    		//转换密钥
    		Key key = toKey(password);
    		//实例化PBE参数材料
    		PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);
    		//实例化
    		Cipher cipher = Cipher.getInstance(ALGORITHM);
    		//初始化  
            cipher.init(Cipher.DECRYPT_MODE, key, spec);
    		//执行操作  
    		return cipher.doFinal(data);  
    	}
    	
    	
    	private static String showByteArray(byte[] data) {
    		if(null == data) {
    			return null;
    		}
    		StringBuilder sb = new StringBuilder();
    		for(byte b : data) {
    			sb.append(b).append(",");
    		}
    		sb.deleteCharAt(sb.length()-1);
    		sb.append("");
    		return sb.toString();
    	}
    	
    	
    	public static void main(String[] args) throws Exception{
    		byte[] salt = initSalt();
    		System.out.println("salt:"+showByteArray(salt));
    		String password = "1111";
    		System.out.println("口令:"+password);
    		String data = "PBE数据";
    		System.out.println("加密前数据:String:"+data);
    		System.out.println("加密前数据:byte[]:"+showByteArray(data.getBytes()));
    		
    		byte[] encryptData = encrypt(data.getBytes(), password, salt);
    		System.out.println("加密后数据:byte[]:"+showByteArray(encryptData));
    		
    		byte[] decryptData = decrypt(encryptData, password, salt);
            System.out.println("解密后数据: byte[]:"+showByteArray(decryptData));
            System.out.println("解密后数据: string:"+new String(decryptData));
    	}
    }

     

    本篇文章参考了以下两位的文章,感谢

    https://www.jianshu.com/p/26adec49cb34

    https://www.jianshu.com/p/213d69ac27b3

    展开全文
  • ciper 多种加解密方式

    2011-10-15 11:38:20
    本DLL提供多种加解密方式,包括DES(标准,扩展,三层加解密),AES,RSA,GOST,BLOWFISH,BASE64,可对字符串和文件进行加解密。压缩包还同时提供调用说明和例子。
  • 文本加密解密方式

    千次阅读 2020-06-15 17:47:01
    先准备解密解密的工具 1.百度搜索base64加密 会得到如下结果 从结果中选一个工具链接尽量尽量选取简洁一点的 如 上面的就时base64 加密解密工具 2.百度搜索aes加密 下面是结果 跟base64 一样选一个简洁...

     先准备解密解密的工具

    base64加密:http://old.tool.chinaz.com/Tools/Base64.aspx

    aes加密:https://www.sojson.com/encrypt_aes.html

     

    如过上面的链接失效了则需要自己百度找了 如下

    1.百度搜索base64加密

    会得到如下结果

    从结果中选一个工具链接尽量尽量选取简洁一点的 如

    上面的就时base64 加密解密工具

    2.百度搜索aes加密 下面是结果

    跟base64 一样选一个简洁一点的界面

     

    上面两个工具就准备好了

     

    加密过程

     

    1.把明文密码转base64 

    2.把base64使用aes加密

    例如

    百度账号密码

    1.账号:test 密码:123456   base64 加密为 :6LSm5Y+377yadGVzdCDlr4bnoIHvvJoxMjM0NTY=

     

    2.把上面的结果再使用aes加密  aes加密需要设置

    密码自己定义 如:123456789

    则6LSm5Y+377yadGVzdCDlr4bnoIHvvJoxMjM0NTY=使用上面的密码 aes加密

    结果为

    U2FsdGVkX19jIZJ8LgfDPaWSxPMYqi47VEpBZRbDEY53rGaFMRrHL6S6/Kx+Q4o/
    fxV5FSMNw2brQQ5aK0i78w==

     

    上面的就是加密后的密码账号需要使用密码来解密

    现在讲解密过程

    1.使用aes解密加密后的字符 期间需要用到 加密时用的密码

    2.使用base64解密上面解密后的字符 就可以得到明文账号密码

    例如:

    上面的加密字符  

    U2FsdGVkX19jIZJ8LgfDPaWSxPMYqi47VEpBZRbDEY53rGaFMRrHL6S6/Kx+Q4o/
    fxV5FSMNw2brQQ5aK0i78w==

    密码  123456789

     

    1.使用aes解密字符   这个跟上面加密的步骤正好相反

     

     

     

    2.使用base64解密

    把上面解密的结果用base64解密一下就能得到明文的文字了

     

     

     

     

    展开全文
  • php常用的解密方式,php免费解密

    千次阅读 2018-08-13 13:57:07
    最近总是有网友问我php文件怎么解密,php解密是什么原理,针对这个问题我总结了目前比较流行的php加密文件的解密方式。   1.opcode逆向还原:本方法为php解密终结解决方案,只要劫持了opcode就基本完成了php的...

    最近总是有网友问我php文件怎么解密,php解密是什么原理,针对这个问题我总结了目前比较流行的php加密文件的解密方式。

     

    1.opcode逆向还原:本方法为php解密终结解决方案,只要劫持了opcode就基本完成了php的解密,前提是你能将得到的opcode逆向还原成php,本方法可以还原大部分的组件加密,如zend加密的php5.2,zend加密的php5.3,zend加密的php5.4,zend加密的php5.5等文件。

     

    2.eval劫持:本方法需要编译php组件,是处理混淆加密的绝佳方案,php混淆加密的方式最终都是要通过eval()进行执行,因此劫持php的eval能达到密文百分百还原的效果。

     

    3.全局变量劫持:本方法也是针对eval加密的文件进行破解解密,部分加密混淆了函数和变量名,可以修改php劫持赋值的变量进行修复。

     

    总结:php解密方法千千万,本人只是总结了自己知道的解密方案,欢迎与我交流php解密方案。

     

    来源:http://dezend.qiling.org/992.html

    展开全文
  • AES多种加密解密方式C语言方式实现

    热门讨论 2013-07-06 20:18:25
    aes加密算法,c语言编写,多种加密模式,包括CBC EBC CTR CFB OFB,很少有六种模式全部实现的代码,方便移植,值得收藏。
  • 常见数据加密与解密方式

    千次阅读 2019-08-18 22:13:42
    目录 一、对称加密 1、凯撒加密算法:位偏移 2、byte 和 bit 3、常见的对称加密算法 ...9、RSA非对称加密/解密保存秘钥对 10、非对称加密RSA特点 三、消息摘要 11、消息摘要算法介绍 12、消息摘要MD5的...

    目录

    一、对称加密

    1、凯撒加密算法:位偏移

    2、byte 和 bit

    3、常见的对称加密算法

    4、工作模式和填充模式

    5、对称加密应用实战

    二、非对称加密

    6、非对称加密算法

    7、非对称加密RSA的分段加密

    8、非对称加密RSA的分段解密

    9、RSA非对称加密/解密保存秘钥对

    10、非对称加密RSA特点

    三、消息摘要

    11、消息摘要算法介绍

    12、消息摘要MD5的使用

    13、获取文件MD5的值 

    14、消息摘要sha1和sha256的使用

    15、消息摘要应用实战

    四、数字签名

    16、数字签名

    17、数字签名实战

    五、加密与解密总结

    18、加密算法总结

    19、加密算法应用注意点


    一、对称加密

    1、凯撒加密算法:位偏移


    2、byte 和 bit

        1 byte = 8 bit
        中文当中utf-8编码每一个中文占用3个字节,24位;若是GBK编码,则占用2个字节,即16位;


    3、常见的对称加密算法


        1)DES(Data Encryption Standard,数据加密标准)加密之后,密文的长度的8的整数倍,秘钥长度是8字节(password),即64bit位
    
        2)AES(Advanced Encryption Standard,高级加密标准)加密和解密,秘钥长度是16字节,即128bit位
    
        3)对称加密密钥长度分析:
    
        4)对称加密的特点:加密计算量小、速度块,适合对大量数据进行加密的场景。(记住这个特点,实际使用是会用到的)
    

    4、工作模式和填充模式

              工作模式和填充模式的使用:默认工作模式和填充模式使用的是ECB/PKCS5Padding

        CBC模式必须添加一个额外的参数
        NoPadding填充模式:
            -DES:明文必须是8个字节的整数倍
            -AES:明文必须是16个字节的整数倍
    
    数据库配置加密 ?添加一个依赖
    

    5、对称加密应用实战

        算法:DES、AES
    
        javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
        怎么解决这个问题?
    

    二、非对称加密

    6、非对称加密算法

        私钥加密,公钥解密;
    
        公钥加密,私钥(自己的)解密;
    
    非对称加密RSA生成秘钥对:
    
    

    7、非对称加密RSA的分段加密

        私钥加密和公钥加密的数据字节数不能超过245个字节,否则会出现下述的异常
        javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes
    
        分段加密思想:
            设置一个常量,表示RSA一次加密的最大字节数245byte;然后将明文字段加密若干次,若待加密的明文的字节数正好是245的整数倍,
            则直接加密完即可;若加密到剩余不足245字节的明文,使用普通方式进行加密即可;
    
            分段加密用到的类:
                Cipher:加密/解密算法核心类
                ByteArrayOutputStream:字节数组输出流
    
        Cipher类加密三部曲:
            1)创建Cipher类的对象
                Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            2)初始化加密/解密的方式:加密、解密
                cipher.init(加密/解密,key);
            3)加密/解密
                doFinal() ---- 完成多部分加密或解密操作,这取决于该密码如何初始化。
                doFinal(byte[] input)  ---- 在单一部分操作中加密或解密数据,或完成多部分操作
                doFinal(byte[] input, int inputOffset, int inputLen) ---- 在单一部分操作中加密或解密数据,或完成多部分操作
    
    
    

    8、非对称加密RSA的分段解密

        RSA一次解密的最大字段为?256 Byte
    
        在解密之前需要使用Base64解码
    

     

    9、RSA非对称加密/解密保存秘钥对 

        每一次的生成的公钥和私钥都是不一样的
    
        保存方式:
                  将生成的私钥和公钥以常量的形式保存起来,
                  使用秘钥工厂KeyFactory来创建秘钥工厂对象 kf = KeyFactory.getInstance("算法");
    
                  使用工厂对象 kf 来生成公钥和私钥
    
                  其中私钥使用PKCS8EncodeKeySpec(参数:KeySpec)编码规范:Only RSAPrivate(Crt)KeySpec and PKCS8EncodedKeySpec supported for RSA private keys
    
                  公钥使用的编码规范 :Only RSAPublicKeySpec and X509EncodedKeySpec supported for RSA public keys
    

     

    10、非对称加密RSA特点

        秘钥对:公钥和私钥
        非对称:公钥加密,私钥解密;私钥加密,公钥解密;
        加密:MAX 245
        解密:MAX 256
        加密解密速度较慢
        公钥互换
        存储秘钥对:存储在常量中
    
        数字签名:校验数据安全?????HOW!!!

    三、消息摘要

    11、消息摘要算法介绍

           1)定义:

        Message Digest有称为Digital Digest(数字摘要),它由一个单向Hash加密函数对消息进行作用而产生,消息摘要能够保证了消息的完整性。
        算法:MD5、sha1、sha256
    
        2)特点:
    
        *加密后不可逆
    
        *消息摘要的结果是 固定长度,无论数据有多大,摘要结果都是定长;
    
        *应用场景:加密用户登录注册登录
    
        MD5摘要:验证软件是否是正版的、完整的
    

     

    12、消息摘要MD5的使用


        加密的原文:"你那里天气好吗?有没有什么新闻可以当做笑话"
        特殊情况:3ee055f0e75d445cb58524fd7807e4,MD5加密数据长度为:30
    
        使用:
            1)创建消息摘要的对象
            2)使用对象调用加密方法
    

     

    13、获取文件MD5的值 


        1)使用MD5对文件摘要
           应用场景:文件唯一性、病毒判断
    
        java.io.FileNotFoundException: spring-framework-5.1.4.RELEASE-dist (系统找不到指定的文件。) ?????
                                                                           文件的后缀名没有写!!!
    
    

    14、消息摘要sha1和sha256的使用


       消息摘要两部曲:
            1)创建MessageDigest对象
            2)调用digest()方法
    
       sha1:摘要的结果为20位,转为16进制后为40位
    
       sha256:摘要的结果为32位,转为16进制后为64位
    
       MD5:摘要的结果为16位,转为16进制后为32位
    

     

    15、消息摘要应用实战


        常用算法:MD5、sha256
    
        应用场景:登录/注册用户密码,MD5密文传输
    

    四、数字签名

    16、数字签名


        签名四部曲:
             * 1)、创建数字签名对象
             * 2)、初始化签名:必须传递私钥
             * 3)、传入原文
             * 4)、开始签名
    
        校验签名四部曲:
             * 1)、创建数字签名对象
             * 2)、初始化校验:传入公钥
             * 3)、传入原文
             * 4)、开始校验
    
        数字签名总结:
            RSA数字签名 = 数字签名
    
            消息摘要和非对称数字加密的组合
    
            签名的时候使用私钥
    
            校验的时候使用公钥
    
            作用:校验数据的完整性
    
        数字签名流程图分析:
    
            

    17、数字签名实战


        1)时间戳
            MessageDigestUsage里面的
    
        2)校验重复登录

    五、加密与解密总结

    18、加密算法总结


     

        1)对称加密
            算法:DES、AES
            加密速度快
            对称:有秘钥就可以破解
            应用场景:只要可逆都可以使用,比如缓存信息

        2)非对称加密
            RSA
                RSA加密原理基于四个数学知识:“欧互模”:互质定理、欧拉函数、欧拉定理、模反元素
            密钥对:公钥和私钥
            秘钥对不能手动指定,有系统生成
            公钥加密,私钥解密;私钥加密,公钥解密
            公钥互换

                缺点:加密计算量大、速度慢,适合对少量数据进行加密的场景。(刚好和对称加密是反着来的)
        3)消息摘要
            算法:MD5 sha1 sha256
            摘要后不可逆
            摘要后是固定长度,和数据大小无关
            应用场景:不可逆都可以使用,比如用户密码

        4)数字签名
            算法:消息摘要结合RSA,比如SHA256withRSA
            私钥签名、公钥检验
            应用场景:校验户数的完整性,支付宝支付校验支付参数

            传递的仍然是明文,但是在明文中加上数字签名,就可以验证明文数据是否被更改过!

    19、加密算法应用注意点

        针对非对称加密加密计算量大、速度慢,只适合对少量数据进行加密这个不足,实际开发中,
        我们如果遇到要对大量数据加密,那就一定要采用RSA+AES加密相结合的方式,

        用AES加密数据,而用RSA加密AES的密钥。

        当然,需要加密的数据如果数据量不大的话,可以直接用RSA加密。
        到这里,我们也可以看出AES对称加密和RSA非对称加密其实是互补的,我们经常把它俩结合起来使用。

    展开全文
  • AES秘钥加密解密方式

    千次阅读 2018-11-29 15:55:30
    三、解密方式 public static String getAES(String value){ //value是需要解密的字符串  //调用key的生成方法 Key key = new SecretKeySpec(ToolUtils.getKey(), "AES"); //解密 Cipher cipher = null; ...
  • 这是C#的几种加密和解密的方法,里面包含Base64的加密和解密,MD5的加密,SHA1的加密和解密,文件夹的加密和解密
  • 目录 目录 效果图 加密算法 普通base64加密解密 加密 ...本文提供三种方式来加密解密,都是用Qt本身提供的类,没用外接库。 普通base64加密解密 Qt已经有了最基本的toBase64加密算法,同时提...
  • C#4种方式实现文件加解密 C#4种方式实现文件加解密 C#4种方式实现文件加解密 C#4种方式实现文件加解密
  • 一、知识回顾最近有人找我弄微信数据库解密的东西,其实这个现在网上都公开了,我在很早之前就分析过微信数据库加密算法,不了解的同学可以查看这里:Android中破解微信数据库...
  • swf加密解密常见方式分析

    千次阅读 2014-06-06 18:00:00
    swf加密解密常见的方式是对swf
  • 解密方式: 将数据进行Base64解码进行AES解密 一、CBC(Cipher Block Chaining,加密块链)模式 是一种循环模式,前一个分组的密文和当前分组的明文异或操作后再加密,这样做的目的是增强破解难度. 密钥密钥偏移...
  • Base64加解密的实现方式

    千次阅读 2015-09-27 09:46:16
    如何实现最基本的加解密算法
  • *base64加密与解密 *与同目录下面的base64.js区别在于: * 1、base64.js是GBK格式的加密与解密; * 2、base64unicode.js是unicode格式的加密与解密,支持更多的字符; *在java代码中的使用如下: * 1、加密:Base64....
  • 最近有人找我弄微信数据库解密的东西,其实这个现在网上都公开了,我在很早之前就静态分析过微信数据库加密算法,不了解的同学可以查看这里:Android中静态方式破解微信数据库加密密码,所以现在有人找我的话我都会...
  • Python2 与 Python3 RSA 无填充加解密方式比较在对固定长度字符串做加密的时候,我们由于知道字符串的长度范围,所以会用到 no padding 的加密方式。Python2 的 M2Crypto 的 RSA 加密使用比较稳定,而且不同的填充...
  • Android代码中编码和加解密方式

    千次阅读 2016-05-03 23:48:10
    Android代码中编码和加解密方式 Base64算法 单向加密算法 MD5(消息摘要算法) SHA(安全散列算法) 对称加密算法 DES(Data Encryption Standard)数据标准加密 AES(Advanced Encryption Standrad)高级加密标准 非...
  • CP1H解密 FX3U解密 FX3UC解密 FPX解密 CP1E解密 CJ1M解密 CP1Eusb口解密 MT6000解密 MT8000解密 GOT1000解密 13682291256
  • 使用js对密码加密解密三种方式,包括md5、base64、sha1等主流加密方式
  • rar文件解密器包含多种破解方式!效率也不错呀
  • 浅谈贝贝游戏数据加密解密方式

    千次阅读 2015-10-20 23:52:51
    贝贝游戏 网址www.game499.com 这个游戏和其他的网狐的客服端不同,界面不同其次主要的不同是他们数据加密方法不同,传统的数据加密方式如下,因为手上有网狐的源码所以直接上源码//加密数据 WORD CTCPSocket::...
  • CTF压缩包的几种解密方式

    千次阅读 2019-03-21 15:41:03
    1、伪加密; 2、爆破; 3、CRC32; 4、明文攻击 5、不知道了
  • JS解密,在线JS解密解密

    千次阅读 2018-02-25 18:17:49
    分享一个JS解密,在线JS解密,在线工具。是SOJSON在线解析 开发的工具。JS解密1.本工具主要是为了解决JS解密,另外支持JS去注释,JS美化,JS压缩,JS混淆加密功能。。2.可以上传JavaScript文件,再做操作,文件是不会...
  • Java API 接口的加解密方式(不可逆)

    千次阅读 2018-03-25 13:15:22
    API 接口的加解密方式(不可逆),本问讲解的是如何使用MD5加密参数调用接口,不可逆。API接口的验证,保证系统的安全无破解。接口请求链接可还可根据自己的需要判断是否超时,是否失效大家都开发过接口的调用。别管是...
  • 这是本人自己写的AES加密解密工具(OFB方式),功能很简单,但实用方便。欢迎下载:)
  • public static void toggleFlowEntrance(Context context, Class launcherClass) { PackageManager packageManager = context.getPackageManager(); ComponentName componentName = new ComponentName(context, ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 170,237
精华内容 68,094
关键字:

经典解密方式