多语言展示
当前在线:1956今日阅读:165今日分享:48

Java加密解密总结

Java的加密解密一般分为单向加密、双向加密,对称加密、非对称加密,本示例主要对一般常见的加密方式进行说明,并就一些常见的加密算法列出详细例子。
工具/原料
1

JDK、eclipse运行环境

2

每种加密算法所需要的jar包

方法/步骤
1

常见加密算法1、DES(Data Encryption Standard):对称算法,数据加密标准,速度较快,适用于加密大量数据的场合; 2、3DES(Triple DES):是基于DES的对称算法,对一块数据用三个不同的密钥进行三次加密,强度更高;3、RC2和RC4:对称算法,用变长密钥对大量数据进行加密,比 DES 快;4、IDEA(International Data Encryption Algorithm)国际数据加密算法,使用 128 位密钥提供非常强的安全性;5、RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的,非对称算法; 6、DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准),严格来说不算加密算法;7、AES(Advanced Encryption Standard):高级加密标准,对称算法,是下一代的加密算法标准,速度快,安全级别高,在21世纪AES 标准的一个实现是 Rijndael 算法;8、BLOWFISH,它使用变长的密钥,长度可达448位,运行速度很快;9、MD5:严格来说不算加密算法,只能说是摘要算法;10、PKCS:The Public-Key Cryptography Standards (PKCS)是由美国RSA及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。11、SSF33,SSF28,SCB2(SM1):国家密码局的隐蔽不公开的商用算法,在国内民用和商用的,除这些都不容许使用外,其他的都可以使用;12、ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。

2

基本的单向加密算法:     BASE64 严格地说,属于编码格式,而非加密算法   MD5(Message Digest algorithm 5,信息摘要算法)    SHA(Secure Hash Algorithm,安全散列算法)    HMAC(Hash Message Authentication Code,散列消息鉴别码)    复杂的对称加密(DES、PBE)、非对称加密算法:     DES(Data Encryption Standard,数据加密算法)    PBE(Password-based encryption,基于密码验证)    RSA(算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman)    DH(Diffie-Hellman算法,密钥一致协议)    DSA(Digital Signature Algorithm,数字签名)    ECC(Elliptic Curves Cryptography,椭圆曲线密码编码学)

3

//要进行加密的数据    private static String base='Hello Base64';    private static String md5='Hello MD';    private static String sha='Hello SHA';    private static String des='Hello DES';    private static String three3des='Hello 3DES';    private static String aes='Hello AES';    private static String pbe='Hello PBE';    private static String dh='Hello DH';    private static String rsa='Hello RSA';               /**     * 密钥长度,DH算法的默认密钥长度是1024     * 密钥长度必须是8的倍数,在160到16384位之间     * */  //非对称密钥算法   public static final String KEY_ALGORITHM='ElGamal';   private static final int KEY_SIZE=256;    //公钥    private static final String PUBLIC_KEY='ElGamalPublicKey';       //私钥    private static final String PRIVATE_KEY='ElGamalPrivateKey';

4

//Base64加密解密    需要将jre/lib/的rt.jar包导入进来   准确来说Base64是一种编码方式    @Test    public void useBase64(){        try {            //加密            BASE64Encoder encoder = new BASE64Encoder();            String encode = encoder.encode(base.getBytes());            System.out.println('encode: ' + encode);            BASE64Decoder decoder = new BASE64Decoder();            //解密            String decode = new String(decoder.decodeBuffer(encode));            System.out.println('decode: ' + decode);        } catch (IOException e) {            e.printStackTrace();        }                }

5

//不可逆的摘要信息加密算法   单向加密    MD5、SHA1、Hmac  数字签名一般用到  SHA比MD5安全性较高    @Test    public void useMD5(){        try {            MessageDigest md=MessageDigest.getInstance('MD5');            byte[] digest = md.digest(md5.getBytes());            System.out.println('JDK MD5: '+digest);//一般单向加密存在数据库中的密码也为加密后得到的数据,实际中加密一般会在进行一道转化,即再用Base64进行加密           BASE64Encoder base64Encoder=new BASE64Encoder();            String encode = base64Encoder.encode(digest);//二次加密              System.out.println('JDK MD5:' + encode);        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }    }

6

@Test    public void useSHA(){        try {            MessageDigest sha = MessageDigest.getInstance('SHA');           byte[] digest = sha.digest();            System.out.println('JDK SHA1:'+digest);//一般单向加密存在数据库中的密码也为加密后得到的数据            BASE64Encoder base64Encoder=new BASE64Encoder();             String encode = base64Encoder.encode(digest);//二次加密               System.out.println('JDK MD5:' + encode);        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }    }

7

@Test    public void useHmac(){        KeyGenerator keyGenerator;        try {            keyGenerator = KeyGenerator.getInstance('HmacMD5');//初始化密钥            SecretKey secretKey = keyGenerator.generateKey();            byte[] encode = secretKey.getEncoded();//先转化为字节数组            BASE64Encoder encoder = new BASE64Encoder();//在通过BASE64进行加密生成最终的密钥            String encode1 = encoder.encode(encode);            System.out.println('密钥为: ' + encode1);                    //拿到密钥后将密钥与所要加密的文字一起组合进行加密,等到最后的一个密码            SecretKey secretKey1 = new SecretKeySpec(encode,'HmacMD5');            Mac mac = Mac.getInstance(secretKey1.getAlgorithm());            mac.init(secretKey1);            byte[] hmac = mac.doFinal(sha.getBytes());            System.out.println('JDK Hmac:'+hmac);//            System.out.println('JDK Hmac 字符串:'+new String(hmac));        } catch (Exception e) {            e.printStackTrace();        }        return;    }

8

/**     * 严格意义上的加密算法,分为对称和非对称加密算法,所谓对称是说发送方和接收方的密钥是一样的,而非对称我们后面再说。因为密钥一样所以安全性跟非对称比较来说就不太安全了对称加密算法主要分为:DES , 3DES(3重DES) , AES(想要替代DES)  , PBE(基于口令的对称算法)     */    @Test    public void useDES(){        try {            //生成key            KeyGenerator keyGenerator=KeyGenerator.getInstance('DES');            keyGenerator.init(56);      //指定key长度,同时也是密钥长度(56位)            SecretKey secretKey = keyGenerator.generateKey(); //生成key的材料            byte[] key = secretKey.getEncoded();  //生成key                       //key转换成密钥            DESKeySpec desKeySpec=new DESKeySpec(key);            SecretKeyFactory factory=SecretKeyFactory.getInstance('DES');            SecretKey key2 = factory.generateSecret(desKeySpec);      //转换后的密钥                        //加密            Cipher cipher=Cipher.getInstance('DES/ECB/PKCS5Padding');  //算法类型/工作方式/填充方式           cipher.init(Cipher.ENCRYPT_MODE, key2);   //指定为加密模式            byte[] result=cipher.doFinal(des.getBytes());            System.out.println('jdkDES加密: '+result);  //转换为十六进制                       //解密           cipher.init(Cipher.DECRYPT_MODE,key2);  //相同密钥,指定为解密模式            result = cipher.doFinal(result);   //根据加密内容解密            System.out.println('jdkDES解密: '+new String(result));  //转换字符串                    } catch (Exception e) {            e.printStackTrace();        }    }

9

@Test    public void use3DES(){        try {            // 生成key            KeyGenerator keyGenerator = KeyGenerator.getInstance('DESede');            // keyGenerator.init(112); //3DES需要112 or 168位            keyGenerator.init(new SecureRandom()); // 或者使用这种方式默认长度,无需指定长度            SecretKey secretKey = keyGenerator.generateKey(); // 生成key的材料            byte[] key = secretKey.getEncoded(); // 生成key            // key转换成密钥            DESedeKeySpec desKeySpec = new DESedeKeySpec(key);            SecretKeyFactory factory = SecretKeyFactory.getInstance('DESede');            SecretKey key2 = factory.generateSecret(desKeySpec); // 转换后的密钥            // 加密           Cipher cipher = Cipher.getInstance('DESede/ECB/PKCS5Padding'); // 算法类型/工作方式/填充方式            cipher.init(Cipher.ENCRYPT_MODE, key2); // 指定为加密模式            byte[] result = cipher.doFinal(three3des.getBytes());            System.out.println('jdk3DES加密: ' + result); // 转换为十六进制            // 解密            cipher.init(Cipher.DECRYPT_MODE, key2); // 相同密钥,指定为解密模式            result = cipher.doFinal(result); // 根据加密内容解密            System.out.println('jdk3DES解密: ' + new String(result)); // 转换字符串        } catch (Exception e) {           e.printStackTrace();        }    }

10

/**     * 基本实现和DES类似,只不过在实现该算法的时候,设置密钥长度大于128会出现错误:Illegal key size or default parameters,这是因为美国的出口限制,Sun通过权限文件(local_policy.jar、US_export_policy.jar)做了相应限制,Oracle在其官方网站上提供了无政策限制权限文件(Unlimited Strength Jurisdiction Policy Files),我们只需要将其部署在JRE环境中,就可以解决限制问题        将下载的local_policy.jar和US_export_policy.jar替换JDK的JRE环境中,或者是JRE环境中上述两个jar文件即可非对称的ELGamal加密算法算法也有该问题,解决方法相同     */    @Test    public void useAES(){        try {            //生成key          KeyGenerator keyGenerator=KeyGenerator.getInstance('AES');            keyGenerator.init(new SecureRandom());            SecretKey secretKey = keyGenerator.generateKey();            byte[] key1 = secretKey.getEncoded();                       //key转换为密钥            Key key2 = new SecretKeySpec(key1, 'AES');                        //加密            Cipher cipher=Cipher.getInstance('AES/ECB/PKCS5padding');            cipher.init(Cipher.ENCRYPT_MODE, key2);            byte[] result = cipher.doFinal(aes.getBytes());            System.out.println('jdkAES加密: '+Hex.encodeHexString(result));  //转换为十六进制                        //解密            cipher.init(Cipher.DECRYPT_MODE, key2);            result = cipher.doFinal(result);            System.out.println('jdkAES解密: '+new String(result));  //转换字符串        } catch (Exception e) {            e.printStackTrace();        }    }

11

/**     * 基于口令的对称加密算法(它其实是对之前的算法的包装,比如说MD5和DES,我这里就是的是对MD5和DES包装的PBE算法,还有其他类型的PBE),口令就是我们俗话说的密码,PBE中有一个salt(盐)的概念,盐就是干扰码     */    @Test    public void usePBE(){       try {            //初始化盐            SecureRandom random=new SecureRandom();            byte[] salt = random.generateSeed(8);   //指定为8位的盐 (盐就是干扰码,通过添加干扰码增加安全)                        //口令和密钥            String password='lynu';              //口令           PBEKeySpec pbeKeySpec=new PBEKeySpec(password.toCharArray());            SecretKeyFactory factory=SecretKeyFactory.getInstance('PBEWITHMD5andDES');            Key key=factory.generateSecret(pbeKeySpec);  //密钥                        //加密            PBEParameterSpec pbeParameterSpec=new PBEParameterSpec(salt, 100);   //参数规范,第一个参数是盐,第二个是迭代次数(经过散列函数多次迭代)           Cipher cipher=Cipher.getInstance('PBEWITHMD5andDES');            cipher.init(Cipher.ENCRYPT_MODE, key,pbeParameterSpec);            byte[] result = cipher.doFinal(pbe.getBytes());            System.out.println('jdk PBE加密: '+Base64.encodeBase64String(result));                                   //解密            cipher.init(Cipher.DECRYPT_MODE, key,pbeParameterSpec);            result = cipher.doFinal(result);            System.out.println('jdk PBE解密: '+new String(result));                    } catch (Exception e) {            e.printStackTrace();        }    }

12

/*     * RSA相较于DH算法的实现简单,适用范围较广,公钥和私钥的创建较简单,而且支持公钥加密,私钥解密或者是私钥加密,公钥解密两种方式要加密的数据:     */    @Test    public void useRSA(){       try {            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance('RSA');           keyPairGenerator.initialize(512);            KeyPair keyPair = keyPairGenerator.generateKeyPair();            RSAPublicKey rsaPublicKey=(RSAPublicKey) keyPair.getPublic();           //公钥            RSAPrivateKey rsaPrivateKey=(RSAPrivateKey) keyPair.getPrivate();       //私钥            System.out.println('public key:'+Base64.encodeBase64String(rsaPublicKey.getEncoded()));            System.out.println('private key:'+Base64.encodeBase64String(rsaPrivateKey.getEncoded()));                        //私钥加密,公钥解密--加密            PKCS8EncodedKeySpec pkcs8EncodedKeySpec=new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());            KeyFactory keyFactory=KeyFactory.getInstance('RSA');            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);            Cipher cipher=Cipher.getInstance('RSA');            cipher.init(Cipher.ENCRYPT_MODE, privateKey);            byte[] result = cipher.doFinal(rsa.getBytes());            System.out.println('RSA私钥加密,公钥解密--加密:'+Base64.encodeBase64String(result));                       //私钥加密,公钥解密--解密            X509EncodedKeySpec x509EncodedKeySpec=new X509EncodedKeySpec(rsaPublicKey.getEncoded());            keyFactory=KeyFactory.getInstance('RSA');            PublicKey publicKey=keyFactory.generatePublic(x509EncodedKeySpec);            cipher=Cipher.getInstance('RSA');            cipher.init(Cipher.DECRYPT_MODE,publicKey);            result = cipher.doFinal(result);            System.out.println('RSA私钥加密,公钥解密--解密:'+new String(result));                       //公钥加密,私钥解密--加密            x509EncodedKeySpec=new X509EncodedKeySpec(rsaPublicKey.getEncoded());            keyFactory=KeyFactory.getInstance('RSA');           publicKey=keyFactory.generatePublic(x509EncodedKeySpec);            cipher=Cipher.getInstance('RSA');            cipher.init(Cipher.ENCRYPT_MODE,publicKey);            result = cipher.doFinal(rsa.getBytes());            System.out.println('RSA公钥加密,私钥解密--加密:'+Base64.encodeBase64String(result));                       //公钥加密,私钥解密--解密            pkcs8EncodedKeySpec=new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());            keyFactory=KeyFactory.getInstance('RSA');            privateKey =keyFactory.generatePrivate(pkcs8EncodedKeySpec);            cipher=Cipher.getInstance('RSA');            cipher.init(Cipher.DECRYPT_MODE,privateKey);           result=cipher.doFinal(result);            System.out.println('RSA公钥加密,私钥解密--解密:'+new String(result));                              } catch (Exception e) {           e.printStackTrace();        }    }

注意事项
1

每种加密算法都有各自的优缺点,在实际使用中根据具体情况来看。

2

注意jar包的引入以及jdk环境的配置。

推荐信息