小谈加密算法

一、为何要用加密

网站中有不少相似金钱、密码等重要业务数据,一旦被监听、拦截,可能会形成严重的损失。
好比下图:前端

咱们能够很容易的看到某个请求的相关参数数据
这里写图片描述java

二、应用场景

加密算法有不少种应用场景,最多见的是用户登陆、身份验证、验签等等。目的在于经过算法,将明文转换为密文。将明文转换为密文只是第一步,更深一步的作法是结合sessionId、随机数、token或者https等,最大限度的防止信息被盗取。算法

三、类型

加密算法一般分为对称性加密算法和非对称性加密算法。后端

3.1 对称性加密

只存在一把钥匙key,若是A想要与B通信,那么A使用钥匙进行加密,B接收到密文的钥匙后,使用钥匙解密,得到明文信息。安全

这里写图片描述

优缺点
效率高、使用维护简单,缺点就是密码一旦泄露,通信信息就会暴露。markdown

经常使用加密算法:
DES、三重DES、AES等,稍后会以AES为例,介绍具体用法。session

3.2 非对称加密

非对称加密有两把钥匙:私钥和公钥。
这里有几个原则和前提须要先说明:
1)公钥和私钥是成对出现的。
2)公开的是公钥,私钥只有本身知道。
3)用公钥加密的信息,只能用对应的私钥进行解密。网站

这里写图片描述

A、B各有一对密钥,A的密钥包括:公钥0一、私钥02,B的密钥包括:公钥0三、私钥04。其中,A拥有B的公钥03,一样的,B也拥有A的公钥01。编码

当A要与B通信时,A使用B的公钥03加密,当B拿到密文后,拿本身的私钥04解密。加密

优缺点:
非对称加密的优缺点正好与对称加密相反,可参照上面。

经常使用加密算法:
RSA,DSA,ECC

除了上面两种主要类型的加密算法,还有一大类是线性散列算法,也叫签名算法。经常使用算法有:MD5,SHA1,HMAC。这类算法能够生成一长串不可逆的密文,常常用在校验数据在传输过程当中是否通过修改。

四、实例

场景:用户登陆,使用res加密,前端js加密,后端解密。

4.1 js文件

//加密key
   var key =CryptoJS.enc.Utf8.parse("*******"); 
   //pwd为加密信息 
   var srcs = CryptoJS.enc.Utf8.parse(pwd); 
   var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});

4.2 后台解密

/** * 密钥,要与加密时的密钥保持一致 */
    private static final String KEY = "*******";
    /** * 算法 */
    private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";

    /** * aes解密 * * @param encrypt * 内容 * @return * @throws Exception */
    public static String aesDecrypt(String encrypt) throws Exception {
        return aesDecrypt(encrypt, KEY);
    }

    /** * aes加密 * * @param content * @return * @throws Exception */
    public static String aesEncrypt(String content) throws Exception {
        return aesEncrypt(content, KEY);
    }

    /** * 将byte[]转为各类进制的字符串 * * @param bytes * byte[] * @param radix * 能够转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制 * @return 转换后的字符串 */
    public static String binary(byte[] bytes, int radix) {
        return new BigInteger(1, bytes).toString(radix);// 这里的1表明正数
    }

    /** * base 64 encode * * @param bytes * 待编码的byte[] * @return 编码后的base 64 code */
    public static String base64Encode(byte[] bytes) {
        return Base64.encodeBase64String(bytes);
    }

    /** * base 64 decode * * @param base64Code * 待解码的base 64 code * @return 解码后的byte[] * @throws Exception */

     public static byte[] base64Decode(String base64Code) throws Exception{
         return StringUtil.isEmpty(base64Code) ? null : new  BASE64Decoder().decodeBuffer(base64Code); 
     }


    /** * AES加密 * * @param content * 待加密的内容 * @param encryptKey * 加密密钥 * @return 加密后的byte[] * @throws Exception */
    public static byte[] aesEncryptToBytes(String content, String encryptKey)
            throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);
        Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
        cipher.init(Cipher.ENCRYPT_MODE,
                new SecretKeySpec(encryptKey.getBytes(), "AES"));

        return cipher.doFinal(content.getBytes("utf-8"));
    }

    /** * AES加密为base 64 code * * @param content * 待加密的内容 * @param encryptKey * 加密密钥 * @return 加密后的base 64 code * @throws Exception */
    public static String aesEncrypt(String content, String encryptKey)
            throws Exception {
        return base64Encode(aesEncryptToBytes(content, encryptKey));
    }

    /** * AES解密 * * @param encryptBytes * 待解密的byte[] * @param decryptKey * 解密密钥 * @return 解密后的String * @throws Exception */
    public static String aesDecryptByBytes(byte[] encryptBytes,
            String decryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);

        Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
        cipher.init(Cipher.DECRYPT_MODE,
                new SecretKeySpec(decryptKey.getBytes(), "AES"));
        byte[] decryptBytes = cipher.doFinal(encryptBytes);

        return new String(decryptBytes);
    }

    /** * 将base 64 code AES解密 * * @param encryptStr * 待解密的base 64 code * @param decryptKey * 解密密钥 * @return 解密后的string * @throws Exception */
    public static String aesDecrypt(String encryptStr, String decryptKey)
            throws Exception {
        return StringUtil.isEmpty(encryptStr) ? null : aesDecryptByBytes(
                base64Decode(encryptStr), decryptKey);
    }

public static void main(String[] args) throws Exception {
        String content = "123456";
        System.out.println("加密前:" + content);

        String encrypt = aesEncrypt(content, KEY);
        System.out.println("加密后:" + encrypt);

        String decrypt = aesDecrypt(encrypt, KEY);
        System.out.println("解密后:" + decrypt);
    }

五、小结

上面说到对称加密和非对称加密各有优缺点,前者效率高,但密钥不安全;后者安全但加密解密时间较长。

实践中比较经常使用的作法是,采用非对称加密算法管理对称算法的密钥,而后用对称加密算法加密数据,这样咱们就集成了两类加密算法的优势,既实现了加密速度快的优势,又实现了安全方便管理密钥的优势。

相关文章
相关标签/搜索