计算机中的密码学

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 密码学是数学和计算机科学的分支,同时其原理涉及大量信息论。密码学的发展促进了计算机科学,特别是在于电脑与网络 安全所使用的技术,如访问控制与信息的机密性。信息的加密几乎在所有的信息通讯中都是很有必要的,尤其是金融类、机密类信息。所以,了解密码学和加密算法对于开发人员来说,也是很有必须的。


一、概述



密码学是数学和计算机科学的分支,同时其原理涉及大量信息论。密码学的发展促进了计算机科学,特别是在于电脑与网络 安全所使用的技术,如访问控制与信息的机密性。信息的加密几乎在所有的信息通讯中都是很有必要的,尤其是金融类、机密类信息。所以,了解密码学和加密算法对于开发人员来说,也是很有必须的。

微信图片1.png

摘要算法是一种单向加密算法,例如SHA、MD5等,这是一种数据完整性的加密,这种单向加密一般称为摘要,而不是真正意义上的加密。因为摘要不可逆,可以防止数据在传输过程中被篡改。可以用于用户登录时验证密码、接口请求时验证参数、文件传输时验证完整性等。

微信图片2.png

对称加密算法是一种基于密钥的加密与解密算法,例如DES、AES等,通信双方共享同一个密钥,双方在通信前商定该密钥,并妥善保管。对称加密有两种方式,一种基于固定密钥,另一种是基于随机源密钥。

微信图片3.png

非对称加密算法中加密使用的密钥和解密使用的密钥不同,一个公开的称为公钥,一个保密的称为私钥。通信双方都有一对自己的公私钥,私钥自己保管好,公钥提供给对方,例如DSA、RSA等。非对称加密的应用场景有两种,一种是公钥加密,私钥解密,另一种是私钥加密,公钥解密。

微信图片4.png对称加密和非对称加密

对称加密速度快、算法公开、计算量小、加密速度快、加密效率高,适用于加密大量数据,但通讯双方需要保护好密钥,存在密钥泄漏的安全风险,而且通讯方的密钥都不一样,所以所拥有的密钥数量巨大,密钥的管理会成为负担。

非对称加密公钥是公开的,私钥不对外公开,只需要维护自己的一组公钥和私钥,在密钥管理上更便利。非对称加密算法强度复杂,加解密算法速度没有对称加密的速度快,但这也保证了其安全性。

针对两种加密方式的优缺点,各大密码机构主张对称加密与非对称加密算法结合使用,使用对称加密算法加密内容,再使用非对称加密算法加密对称算法的密钥。

微信图片5.jpg

二、应用场景



MD5实现用户登录


在设计一个用户登录系统时,用户的密码不管是在网络传输中,还是存在数据库中,都不应该是明文。一般会选用摘要算法来对密码进行加密,在传输和存储时都是使用加密后的Hash密文。比如使用MD5对密码进行加密,在注册时将密码明文通过MD5加密,然后存储在数据库中,登录时客户端同样对密码进行加密,然后在服务端与数据库中的Hash密文对比,通过判断两个Hash密文是否一致来决定是是否登录成功。这样处理的好处是,即使数据库中的密码泄漏了,也不会知道密码明文。

微信图片6.png只要明文相同,MD5加密后的密文就相同,于是攻击者就可以通过撞库的方式来破解出明文。加盐就是向明文中加入随机数,然后在生成MD5,这样一来即使明文相同,每次生成的MD5码也不同,如此就加大了暴力破解的难度。


要算法实现参数验签


摘要算法可以任意大的数据压缩成摘要,使得数据量变小,将数据的格式转换成固定位数的Hash码。这可以给任何一种数据创建小的数字“指纹”,这就可以用来判断数据的完整性,判断数据在传输过程中是否被篡改,从而满足安全性需要。例如,我们要设计有一定安全性要求的接口,需要对接口参数进行完整性验证,可以在请求参数中添加一个字段存放所有业务字段的摘要Hash码,这样做的话,即使在接口请求的过程中被黑客攻击修改了参数信息,也不会成功请求服务,从而破坏正常业务。微信图片7.png


Git保证完整性


Git中所有数据在存储前都计算校验和,然后以校验和来引用。这意味着不可能在Git不知情时更改任何文件内容或目录内容。这个功能建构在Git底层,是构成Git哲学不可或缺的部分。若你在传送过程中丢失信息或损坏文件,Git就能发现。Git用以计算校验和的机制叫做SHA-1散列(摘要算法),它会基于Git中文件的内容或目录结构计算出来一个Hash码。

24b9da6552252987aa493b52f8696cd6d3b00373

Git中使用这种Hash码的情况很多,实际上,Git数据库中保存的信息都是以文件内容的Hash码来索引,而不是文件名。


非对称加密实现数字签名


数字签名是一种功能类似写在纸上的普通签名,使用非对称加密领域的技术,一套数字签名算法通常包括两种运算,一个用于签名,另一个用于验证。在使用非对称加密时,通常我们使用公钥加密,用私钥解密,而在数字签名中,我们使用私钥加密(生成签名),公钥解密(验证签名)。前面说过非对称加密算法的复杂性,所以通常我们会对消息内容的Hash值签名,因为Hash值长度远远小于消息原文,使得签名(非对称加密)的效率大大提高。

微信图片8.png

公钥和私钥都可以用于加解密操作,用公钥加密的数据只能由对应的私钥解密,反之亦然。虽说两者都可用于加密,但是不同场景使用不同的密钥来加密,当私钥用于签名,公钥用于验签时,签名和加密作用不同,签名并不是为了保密,而是为了保证这个签名是由特定的某个人签名的,而不是被其它人伪造的签名,所以私钥的私有性就适合用在签名用途上。私钥签名后,只能由对应的公钥解密,公钥又是公开的(很多人可持有),所以这些人拿着公钥来解密,解密成功后就能判断出是持有私钥的人做的签名,验证了身份合法性。

公钥加密,私钥解密,才是真正的加密;私钥加密,公钥解密用于签名。


SSH协议加密分析


SSH是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH最常见的用途是远程登录系统,通常用来传输命令行界面和远程执行命令。SSH的使用在类Unix系统(Linux系统)最为常见,不过在Windows10 1809版本也提供了Open SSH工具。在使用SSH客户端登录时,SSH提供两种级别的安全验证:

  • 第一种级别(基于密码的安全验证),使用帐号和密码登录到远程主机,并且所有传输的数据都会被加密。但是,可能会有别的服务器在冒充真正的服务器,无法避免被“中间人”攻击。
  • 第二种级别(基于密钥的安全验证),需要依靠密钥,也就是你必须为自己创建一对密钥,并把公有密钥放在需要访问的服务器上。客户端会向服务器发出请求,请求用你的密钥进行安全验证。服务器收到请求之后,先在你在该服务器的用户根目录下寻找你的公有密钥,然后把它和你发送过来的公有密钥进行比较。如果两个密钥一致,服务器就用公有密钥加密“质询”(challenge)并把它发送给客户端软件。从而避免被“中间人”攻击。

微信图片9.pngSSH使用密钥验证时,使用了摘要算法和非对称加密算法,已许可登录的公钥保存在用户的 ~/.ssh/authorized_keys 文件中。


三、实现案例



1. SHA


安全散列算法(SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的几率很高。实现代码如下:

public class Main {
    public static void main(String[] args) throws Exception {
        MessageDigest sha = MessageDigest.getInstance("SHA");
        sha.update("码匠公众号".getBytes());
        System.out.println(byteToString(sha.digest()));
        MessageDigest sha224 = MessageDigest.getInstance("SHA-224");
        sha224.update("码匠公众号".getBytes());
        System.out.println(byteToString(sha224.digest()));
        MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
        sha256.update("码匠公众号".getBytes());
        System.out.println(byteToString(sha256.digest()));
    }
    private static String byteToString(byte[] arr) {
        StringBuilder res = new StringBuilder();
        for (byte b : arr) {
            res.append(String.format("%02X", b));
        }
        return res.toString();
    }
}


2. MD5


MD5消息摘要算法,一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致,将数据(如一段文字)运算变为另一固定长度值,是散列算法的基础原理。代码实现如下:

public class Main {
    public static void main(String[] args) throws Exception {
        MessageDigest sha = MessageDigest.getInstance("MD5");
        sha.update("码匠公众号".getBytes());
        System.out.println(byteToString(sha.digest()));
    }
    private static String byteToString(byte[] arr) {
        ......
    }
}

MD5算法无法防止碰撞,因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。


3. DES


数据加密标准(DES)是一种对称密钥加密块密码算法,实现代码如下:

public class Main {
    public static void main(String[] args) {
        String str = "码匠公众号";
        String password = "CodeArtist";
        byte[] encrypt = encrypt(str.getBytes(), password);
        System.out.println("密文: " + byteToString(encrypt));
        byte[] decrypt = decrypt(encrypt, password);
        System.out.println("明文: " + new String(decrypt));
    }
    /**
     * 加密
     */
    public static byte[] encrypt(byte[] src, String password) {
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(password.getBytes());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secureKey = keyFactory.generateSecret(desKey);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, secureKey, random);
            return cipher.doFinal(src);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 解密
     */
    public static byte[] decrypt(byte[] encrypt, String password) {
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(password.getBytes());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secureKey = keyFactory.generateSecret(desKey);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, secureKey, random);
            return cipher.doFinal(encrypt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    private static String byteToString(byte[] arr) {
        ......
    }
}


4. AES


高级加密标准(AES)是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。实现代码如下:

public class Main {
    public static void main(String[] args) {
        String str = "码匠公众号";
        String password = "CodeArtist";
        byte[] encrypt = encrypt(str.getBytes(), password);
        System.out.println("密文: " + byteToString(encrypt));
        byte[] decrypt = decrypt(encrypt, password);
        System.out.println("明文: " + new String(decrypt));
    }
    /**
     * 加密
     */
    public static byte[] encrypt(byte[] src, String password) {
        try {
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            keygen.init(128, new SecureRandom(password.getBytes()));
            byte[] raw = keygen.generateKey().getEncoded();
            SecretKey key = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance(keygen.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, key);
            return cipher.doFinal(src);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 解密
     */
    private static byte[] decrypt(byte[] encrypt, String password) {
        try {
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            keygen.init(128, new SecureRandom(password.getBytes()));
            byte[] raw = keygen.generateKey().getEncoded();
            SecretKey key = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance(keygen.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, key);
            return cipher.doFinal(encrypt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    private static String byteToString(byte[] arr) {
        ......
    }
}


5. DSA


数字签名算法(DSA)是用于数字签名的联邦信息处理标准,该算法使用由公钥和私钥组成的密钥对。私钥用于生成消息的数字签名,并且可以通过使用签名者的相应公钥来验证这种签名。数字签名提供信息鉴定(接收者可以验证消息的来源),完整性(接收方可以验证消息自签名以来未被修改)和不可否认性(发送方不能错误地声称它们没有签署消息)。实现代码如下:

public class Main {
    public static void main(String[] args) throws Exception {
        String data = "码匠公众号";
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
        kpg.initialize(512);
        KeyPair keypair = kpg.generateKeyPair();
        DSAPublicKey publicKey = (DSAPublicKey) keypair.getPublic();
        DSAPrivateKey privateKey = (DSAPrivateKey) keypair.getPrivate();
        Signature signature = Signature.getInstance("SHA1withDSA");
        byte[] sign = sign(signature, data.getBytes(), privateKey);
        boolean result = verify(signature, data.getBytes(), sign, publicKey);
        System.out.println(result);
    }
    /**
     * 签名
     */
    public static byte[] sign(Signature signature, byte[] data, DSAPrivateKey privateKey) {
        try {
            signature.initSign(privateKey);
            signature.update(data);
            return signature.sign();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 验证
     */
    public static boolean verify(Signature signature, byte[] data, byte[] sign, DSAPublicKey publicKey) {
        try {
            signature.initVerify(publicKey);
            signature.update(data);
            return signature.verify(sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}


6. RSA


RSA加密算法是一种非对称加密算法,在公开密钥加密和电子商业中被广泛使用。对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式破解。到当前为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被破解的。实现代码如下:

public class Main {
    public static void main(String[] args) throws Exception {
        String data = "码匠公众号";
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024);
        KeyPair keypair = kpg.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keypair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keypair.getPrivate();
        byte[] encrypt = encrypt(data.getBytes(), publicKey);
        System.out.println("密文: " + byteToString(encrypt));
        byte[] decrypt = decrypt(encrypt, privateKey);
        System.out.println("明文: " + new String(decrypt));
        System.out.println();
    }
    /**
     * 加密
     */
    public static byte[] encrypt(byte[] src, RSAPublicKey publicKey) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey key = keyFactory.generatePublic(new X509EncodedKeySpec(publicKey.getEncoded()));
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, key);
            return cipher.doFinal(src);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 解密
     */
    public static byte[] decrypt(byte[] encrypt, RSAPrivateKey privateKey) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey key = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKey.getEncoded()));
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, key);
            return cipher.doFinal(encrypt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    private static String byteToString(byte[] arr) {
        ......
    }
}


四、英文缩写对照



英文缩写 英文全拼 中文
SHA Secure Hash Algorithm 安全散列算法
MD Message Digest 信息摘要
DES Data Encryption Standard 数据加密标准
AES Advanced Encryption Standard 高级加密标准
DSA Digital Signature Algorithm 数字签名算法
RSA - 一种非对称加密算法
SSH Secure Shell 安全外壳协议
目录
相关文章
|
7月前
|
安全 数据安全/隐私保护
密码学系列之一:密码学的前世今生
密码学系列之一:密码学的前世今生
|
Rust 算法 数据安全/隐私保护
【密码学】一文读懂XTEA加密
本篇文章,我们来看一下上一次讲过的TEA加密算法的一个升级版XTEA, 相比于TEA, XTEA的安全性显然是更高的,其中的过程要比TEA稍微复杂一点点。
1285 0
【密码学】一文读懂XTEA加密
|
3月前
|
算法 安全 搜索推荐
深入理解密码学技术
深入理解密码学技术
44 1
|
安全 算法 数据安全/隐私保护
我对密码学的理解
密码学(Cryptography),是一门将信息进行加密处理与传递,以及分析加密信息的学科。 密码学即保密技术,是一门研究如何保证信息传输的安全技术,是数字信息及其他形式的信息如何防止未经授权的使用及访问的学科。
93 2
|
存储 算法 安全
【11.10】现代密码学1——密码学发展史:密码学概述、安全服务、香农理论、现代密码学
【11.10】现代密码学1——密码学发展史:密码学概述、安全服务、香农理论、现代密码学
240 0
|
算法 安全 Serverless
密码学 Cryptology 的基本概念术语
密码学 Cryptology 的基本概念术语
137 2
|
算法 安全 数据安全/隐私保护
现代密码学 | 03:分组密码
现代密码学 | 03:分组密码
389 0
|
存储 算法 安全
密码学-回顾篇(下)
密码学-回顾篇
244 0
|
编解码 并行计算 算法
密码学-回顾篇(上)
密码学-回顾篇
225 0
|
定位技术
【密码学】一文读懂零知识证明
本文来聊一聊零知识证明的一点知识, 本文的例子纯属虚构,故事素材来源于网络和论文,以及我的瞎编, 如有雷同, 纯属巧合。
【密码学】一文读懂零知识证明