A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 大山哥哥 黑马粉丝团   /  2019-7-27 22:01  /  1636 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 大山哥哥 于 2019-7-27 22:08 编辑

        最近有很多同学接触到了加密相关的内容,我们的课程中也涉及到了一部分加密算法的使用。但是由于时间关系,并没有非常深入的跟大家探讨加密的相关技术。今天我们就详细的来说一说主流加密算法的分类及各自的简单实现。
        众所周知,网络上传递的很多数据,我们是不希望让“别有用心”的人获取到的,所以就产生了加密的需求。而数据有的加密,就会有人想要去解密。就像武侠小说中的正邪两派一样互相纠缠。而自然而然的就催生出了一系列的加密算法。数据加密就是对原来为明文的文件或数据按某种算法进行处理,使其成为通常称为“密文”的一段信息。通过这样的途径,来达到信息保护的目的。而解密,也就是加密的逆操作,代表把刚才说的“密文”还原为之前的数据供我们使用。我们现在常见的加密算法,有对称加密算法、非对称加密算法和散列摘要算法几种,我们一个个来看一看。
对称加密
        对称加密算法使用的比较早,安全性略低。加密时,把数据原文和密钥一起进行运算,得到一个谁也无法识别的密文,这样的密文经过网络传输后,得到数据的一方要使用和加密时相同的密钥对密文进行逆运算,则把数据还原。举个例子:加密就是把原文所有数据“+1”,而解密就是把密文都“-1”。        AES、DES、3DES 都是对称的块加密算法,加解密的过程是可逆的。其中,DES算法使用的密钥长度为56位,相当于如果想要穷举破解,最多需要计算2ˆ56次。所以安全性较低。而3DES,看名字就知道,是DES算法的3次迭代,就是把DES加密后的数据换一个新的密钥再用DES算法加密两次。如果不是非常敏感的数据,DES算法已经足够使用了。
        AES算法是为了取代DES算法而出现的,它采用了密码学的高级加密标准,密钥最少支持128位、192位和256位。所以对比DES,更加安全,也更加灵活高效。参考代码如下:
[AppleScript] 纯文本查看 复制代码
import net.pocrd.annotation.NotThreadSafe;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;

public class AesHelper {
    private SecretKeySpec keySpec;
    private IvParameterSpec iv;

    public AesHelper(byte[] aesKey, byte[] iv) {
        if (aesKey == null || aesKey.length < 16 || (iv != null && iv.length < 16)) {
            throw new RuntimeException("初始密钥长度错误");
        }
        if (iv == null) {
            iv = Md5Util.md5(aesKey);
        }
        keySpec = new SecretKeySpec(aesKey, "AES");
        this.iv = new IvParameterSpec(iv);
    }

    public AesHelper(byte[] aesKey) {
        if (aesKey == null || aesKey.length < 16) {
            throw new RuntimeException("密钥长度错误");
        }
        keySpec = new SecretKeySpec(aesKey, "AES");
        this.iv = new IvParameterSpec(Md5Util.compute(aesKey));
    }

    public byte[] encrypt(byte[] resource) {
        byte[] result = null;
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("AES/CFB/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            result = cipher.doFinal(resource);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    public byte[] decrypt(byte[] secret) {
        byte[] result = null;
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("AES/CFB/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
            result = cipher.doFinal(secret);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    public static byte[] randomKey(int size) {
        byte[] result = null;
        try {
            KeyGenerator gen = KeyGenerator.getInstance("AES");
            gen.init(size, new SecureRandom());
            result = gen.generateKey().getEncoded();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }
}

非对称加密
        非对称加密算法的机制会略复杂,它会使用两个成对的密钥进行计算。其中一个叫做“公钥”,也就是公开的密钥,相当于谁都可以获取到的一个密钥。而另一个是“私钥”,这个是私有的,并不会公开。而在数据进行加密时,公钥和私钥是配对使用的。一个公钥对应一个私钥。数据可以使用公钥加密,也可以使用私钥加密。而公钥加密的数据,只有用私钥才能解密。同样的,私钥加密的数据,只有使用公钥才能解开。这样,如果两个人A和B需要传递数据。A可以生成一堆密钥,先把公钥通过网络传输给B,这个过程即使公钥被拦截泄露也不影响。此时B用A传递过来的公钥加密数据传给A,然后A使用自己的私钥进行解密即可。由于整个过程中,A的私钥并不会传输出去,所以公钥丢失也不会被人把数据破解。        RSA加密算法大家应该都见过,特别是使用GIT提交代码时,如果你用过SSH协议传输,这个算法一定不陌生。RSA是目前最有影响力的公钥加密算法,并且被普遍认为是目前最优秀的公钥方案之一。RSA能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。
        还有一种加密算法叫做ECC,它比RSA使用的密钥更小,但是它的运算比RSA消耗更多性能,对CPU的要求更高,所以在一些需要考虑性能的场景不推荐使用。
摘要算法
        严格意义上来说,摘要算法并不是用于加密解密数据的,因为摘要算法的密文并不能还原为原文。例如:MD5算法,无论多长的数据,经过MD5计算之后都会输出一个128bit的数据。而相同的数据通过MD5计算出的结果是相同的,所以MD5一般用于做文件的完整性校验。在Java中,我们可以非常方便的使用MD5来进行运算。
[AppleScript] 纯文本查看 复制代码
public static final byte[] md5(byte[] source) {
    try {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        return md5.digest(source);
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}
        当然,常见的摘要算法还有SHA1,只不过SHA1的安全性比MD5更强一些。同样的,在Java中我们可以很容易使用它。
[AppleScript] 纯文本查看 复制代码
public static final byte[] md5(byte[] source) {
    try {
        MessageDigest md5 = MessageDigest.getInstance("SHA1");
        return md5.digest(source);
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}

        以上就是现在主流的一些加密算法的介绍了,希望对想了解加密算法的同学有一些帮助。

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马