常见加密算法介绍

一、背景:

  1. 在古代,人们经常需要传递重要的消息、指令和情报,但是这些信息往往容易被敌人截获并解读。为了保护通信的机密性,人们开始使用密码加密。

  2. 密码加密的目的是将明文信息转化为一种难以理解的形式,使得只有掌握加密密钥或规则的人才能解读。最早的密码加密方法包括替换密码和移位密码。替换密码是将字母按照一定规则进行替换,例如将每个字母向后移动几个位置。移位密码是将字母按照一定的位移进行重新排列。

  3. 随着时间的推移,密码加密方法不断演化和改进。在现代密码学中,出现了更加复杂和安全的加密算法,如对称加密算法和非对称加密算法。对称加密算法使用相同的密钥进行加密和解密,而非对称加密算法使用一对密钥,公钥用于加密,私钥用于解密。

  4. 密码加密在军事、外交、商业和个人通信中都起到了重要作用。它可以确保通信的机密性,阻止未经授权的人读取和理解信息。同时,密码加密也面临着破解的挑战。随着计算机和技术的发展,密码学家和黑客之间的竞争变得更加激烈,破解密码的技术也不断进步。

  5. 总的来说,密码加密的背景可以追溯到古代,人们意识到保护通信和信息的重要性。随着时间的推移,密码加密方法不断演化和改进,同时也面临着破解的挑战。密码加密在保护通信和信息安全方面起到了重要作用。

二、几种常见的加密算法

当谈到算法时,通常可以将其整体上分为不可逆加密和可逆加密,而可逆加密又可以进一步分为对称加密和非对称加密。
JIAMI

1. 不可逆加密算法(哈希算法):

  1. 不可逆加密算法将输入数据转换为固定长度的哈希值,不可逆地隐藏了原始数据,无法从哈希值还原出原始数据。常见的不可逆加密算法包括MD5、SHA-1SHA-256等。

  2. 不可逆算法,也称为哈希算法,是一种将输入数据转换为固定长度的输出值的算法。不可逆算法的特点是无法从输出值还原出原始的输入数据。这意味着一旦数据被不可逆算法处理,就无法逆向操作以获取原始数据。

  3. 不可逆算法的输出值通常被称为哈希值或摘要。它们具有以下特点:

  • 唯一性:不同的输入数据会生成不同的哈希值。即使输入数据的细微变化,也会导致完全不同的哈希值。

  • 不可逆性:无法从哈希值还原出原始输入数据。即使知道哈希算法的具体细节,也无法逆向计算出原始数据。

  • 固定长度:不可逆算法生成的哈希值通常具有固定的长度。无论输入数据的大小,输出的哈希值长度是固定的。

  1. 不可逆算法常用于数据完整性校验、密码存储和数字签名等领域。常见的不可逆算法有MD5、SHA-1和SHA-256等。由于技术的进步和安全性的考虑,一些早期的不可逆算法已经不再被推荐使用。

1.1 MD5

MD5(Message Digest Algorithm 5)是一种常用的不可逆哈希算法。以下是MD5算法的优点和缺点:

1.1.1 优点:
  1. 快速性:MD5算法的计算速度相对较快,适用于对大量数据进行哈希计算。

  2. 广泛应用:MD5算法被广泛应用于数据完整性校验、密码存储和数字签名等领域,且在许多系统和编程语言中都有现成的实现。

  3. 固定长度:MD5算法生成的哈希值长度固定为128位,无论输入数据的长度是多少,都会生成一个固定长度的哈希值。

1.1.2 缺点:
  1. 易碰撞:由于MD5算法的哈希值长度较短,存在相同哈希值的不同输入数据,即碰撞。因此,MD5算法在密码存储等安全性要求较高的场景下不再安全。

  2. 不可逆性:尽管MD5算法是不可逆的,无法从哈希值还原出原始输入数据,但通过预先计算哈希值的数据库或彩虹表等方式,仍然可以进行暴力破解。

  3. 容易受到攻击:由于MD5算法的设计缺陷,它容易受到碰撞攻击、预计算攻击和彩虹表攻击等。因此,MD5算法不再被推荐用于安全性要求较高的场景。

1.1.3 Demo:

以下是使用Java代码编写的简单MD5哈希算法的示例:

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Demo {
    public static void main(String[] args) {
        String input = "Hello, World!";
        String md5Hash = calculateMD5(input);
        System.out.println("MD5哈希值: " + md5Hash);
    }

    public static String calculateMD5(String data) {
        try {
            // 创建MD5哈希对象
            MessageDigest md5 = MessageDigest.getInstance("MD5");

            // 将数据转换为字节数组并计算哈希值
            byte[] dataBytes = data.getBytes();
            byte[] md5Bytes = md5.digest(dataBytes);

            // 将字节数组转换为十六进制字符串
            BigInteger md5Value = new BigInteger(1, md5Bytes);
            String md5Hash = md5Value.toString(16);

            // 补齐字符串长度为32位
            while (md5Hash.length() < 32) {
                md5Hash = "0" + md5Hash;
            }

            return md5Hash;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}
1.1.4 案例分析:
  1. 以上示例代码使用Java的MessageDigest类和BigInteger类来计算和表示MD5哈希值。
  2. 首先,我们创建一个MD5哈希对象,然后将要哈希的数据转换为字节数组,并使用digest()方法计算哈希值。
  3. 接下来,我们将字节数组转换为十六进制字符串表示,并使用BigInteger类来处理大整数。
  4. 最后,我们补齐字符串长度为32位,并返回MD5哈希值。

1.2 SHA-256

SHA-256是SHA系列算法中的一种,它提供了较高的安全性,但也存在一些缺点,包括:

  1. 算法长度:SHA-256生成的哈希值长度为256位,相对于较短的哈希算法(如MD5和SHA-1),SHA-256生成的哈希值较长,可能会占用更多的存储空间。

  2. 计算速度:由于SHA-256算法的复杂性,相对于较弱的哈希算法,SHA-256的计算速度较慢。这可能会在某些性能敏感的场景中产生影响。

  3. 可逆性:SHA-256是一种单向哈希算法,不可逆转。这意味着无法从SHA-256哈希值推导出原始数据,因此在某些应用场景中可能会有限制。

1.2.1 Demo:

下面是一个使用Java编写的SHA-256算法的Demo:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHA256Demo {

    public static void main(String[] args) {
        String input = "Hello, World!";
        String sha256Hash = getSHA256Hash(input);
        System.out.println("SHA-256 Hash: " + sha256Hash);
    }

    public static String getSHA256Hash(String input) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            byte[] hashBytes = messageDigest.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte hashByte : hashBytes) {
                String hex = Integer.toHexString(0xff & hashByte);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
}
1.2.2 案例分析:
  1. 这个示例使用Java的MessageDigest类来计算SHA-256哈希值。
  2. getSHA256Hash方法接受一个字符串输入,并返回对应的SHA-256哈希值的十六进制字符串表示。
  3. 在main方法中,我们将输入字符串设置为"Hello, World!",并打印SHA-256哈希值。

1.3 SHA#MD5对比

  1. 哈希长度:SHA算法生成的哈希值长度可达到160位、224位、256位、384位或512位,而MD5算法生成的哈希值长度仅为128位。更长的哈希长度提供了更大的密码空间,使得攻击者更难以通过暴力破解或碰撞攻击来找到相同的哈希值。

  2. 安全性:SHA算法设计时考虑了MD5算法存在的一些弱点,并采用了更复杂的算法结构和更多的运算步骤,增加了抗碰撞和抗碰撞攻击的能力。SHA算法的设计目标是提供更高的安全性和可靠性。

  3. 算法结构:SHA算法的设计与MD5算法不同,包括不同的数据处理方式、轮数、轮函数等。SHA算法的结构更复杂且更安全,能够提供更强的保护机制。

  4. 广泛应用:由于MD5算法的弱点,它不再被推荐用于安全敏感的应用场景。而SHA算法被广泛应用于密码学领域,包括数字签名、SSL/TLS等安全协议,以及密码存储、消息认证等场景。

  5. 总的来说,SHA算法相对于MD5算法具有更高的安全性和抗碰撞能力,更适合用于保护敏感信息的哈希操作。但需要注意的是,随着计算技术的发展,SHA算法的某些变种也可能会面临安全性的挑战,因此在选择哈希算法时应考虑最新的安全标准和推荐算法。

2. 可逆加密算法:

2.1. 对称加密算法:

对称加密算法使用相同的密钥进行加密和解密。常见的对称加密算法包括DES、AES3DES等。

2.1.1 DES

DES算法是一种对称密钥加密算法,于1976年由IBM提出,并在当时成为标准加密算法,但由于密钥长度较短和安全性问题,已被更安全的AES算法取代。
下面是一个简单的DES(Data Encryption Standard)加密和解密的示例代码:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class DESDemo {
    public static void main(String[] args) {
        try {
            // 设置密钥
            String secretKey = "abcdefgh";
            DESKeySpec desKeySpec = new DESKeySpec(secretKey.getBytes());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey key = keyFactory.generateSecret(desKeySpec);

            // 创建加密和解密的实例
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key);

            // 加密字符串
            String plainText = "Hello, World!";
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
            String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
            System.out.println("加密后的字符串:" + encryptedText);

            // 切换为解密模式
            cipher.init(Cipher.DECRYPT_MODE, key);

            // 解密字符串
            byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
            String decryptedText = new String(decryptedBytes, StandardCharsets.UTF_8);
            System.out.println("解密后的字符串:" + decryptedText);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  1. 这个示例使用Java中的javax.crypto包来实现DES加密和解密。首先,通过密钥生成一个SecretKey对象。然后,创建一个Cipher对象,并使用密钥初始化它。在加密模式下,将明文字符串转换为字节数组,调用doFinal方法进行加密,并使用Base64编码将加密结果转换为字符串。在解密模式下,将Base64编码的字符串转换为字节数组,调用doFinal方法进行解密,并将解密结果转换为字符串。

  2. DES是一种对称加密算法,使用相同的密钥进行加密和解密。这个示例中使用了ECB(电子密码本)模式和PKCS5Padding填充方式。DES算法已经被认为不够安全,因此在实际应用中更常见的是使用更安全的AES算法。

2.1.2 AES

AES(Advanced Encryption Standard)是一种对称加密算法,由美国国家标准与技术研究院(NIST)于2001年发布,用于替代旧有的DES加密算法。它采用128位、192位或256位密钥长度,具有较高的安全性、效率和广泛应用性,被广泛用于保护敏感信息的机密性和安全性。
以下是一个简单的Java示例代码,用于演示如何使用AES算法进行加密和解密:

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class AESDemo {
    private static final String ALGORITHM = "AES";

    public static void main(String[] args) {
        try {
            String plaintext = "Hello, AES!";
            String key = "MySecretKey";

            byte[] encrypted = encrypt(plaintext, key);
            System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encrypted));

            String decrypted = decrypt(encrypted, key);
            System.out.println("Decrypted: " + decrypted);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static byte[] encrypt(String plaintext, String key) throws Exception {
        SecretKeySpec secretKey = generateKey(key);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
    }

    public static String decrypt(byte[] ciphertext, String key) throws Exception {
        SecretKeySpec secretKey = generateKey(key);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decryptedBytes = cipher.doFinal(ciphertext);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

    public static SecretKeySpec generateKey(String key) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        keyGenerator.init(128);
        SecretKey secretKey = keyGenerator.generateKey();
        return new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
    }
}

这个示例演示了如何使用AES算法进行文本的加密和解密。它首先使用指定的密钥生成一个SecretKeySpec对象,然后使用该密钥进行加密和解密操作。加密后的结果以Base64编码的形式输出,解密后的结果以字符串形式输出。

简要分析:

  • 生成密钥:使用KeyGenerator类生成密钥,其中指定了算法为AES,密钥长度为128位。
  • 加密:使用Cipher类的ENCRYPT_MODE模式和生成的密钥对明文进行加密操作,得到加密后的字节数组。
  • 解密:使用Cipher类的DECRYPT_MODE模式和生成的密钥对加密后的字节数组进行解密操作,得到原始明文字符串。
  • 输出:加密后的结果以Base64编码形式输出,解密后的结果以字符串形式输出。
    需要注意的是,这只是一个简单的示例,实际应用中还需要考虑更多的安全性和异常处理。

2.3 DES#AES对比

DES(Data Encryption Standard)和AES(Advanced Encryption Standard)都是对称加密算法,它们之间的主要区别如下:

  • 密钥长度:DES使用56位密钥,AES则有128位、192位和256位三种密钥长度可选。AES的密钥长度更长,提供更高的安全性。

  • 加密速度:由于密钥长度不同,AES相对于DES具有更快的加密速度。AES加密速度比DES快得多,并且能够更好地适应现代计算机硬件。

  • 安全性:由于DES的密钥较短,已经被证明存在一些安全性问题。而AES使用更长的密钥长度和更强大的算法,被广泛认为是更安全的加密算法。

  • 算法结构:DES使用分组加密算法,每个分组64位;AES使用分组加密算法,分组长度可以是128位、192位或256位。

  • 使用范围:由于DES的安全性问题,现在很少在实际应用中使用。而AES被广泛应用于各种领域,如网络通信、数据库加密、文件加密等。

总体而言,AES相对于DES具有更高的安全性和更快的加密速度,在现代加密需求中更为适用。

2.4. 非对称加密算法:

非对称加密算法使用一对密钥,公钥用于加密,私钥用于解密。常见的非对称加密算法包括RSA和ECC等。

2.4.1. RSA

在1978年,Ron Rivest、Adi Shamir和Leonard Adleman三位科学家合作发明了RSA算法,这是目前应用最广泛的非对称加密算法。这个算法的名字正是由这三位科学家的姓氏首字母组成。
以下是一个使用Java编写的简单RSA算法的示例:

import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;

public class RSAExample {
    public static void main(String[] args) {
        try {
            // 生成RSA密钥对
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048); // 设置密钥长度
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();

            // 加密
            String originalText = "Hello, World!";
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedBytes = cipher.doFinal(originalText.getBytes());

            // 解密
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            String decryptedText = new String(decryptedBytes);

            // 打印结果
            System.out.println("原始文本:" + originalText);
            System.out.println("加密后的文本:" + new BigInteger(1, encryptedBytes).toString(16));
            System.out.println("解密后的文本:" + decryptedText);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

上述代码中,首先使用KeyPairGenerator类生成一个2048位的RSA密钥对。然后,使用公钥进行加密和私钥进行解密。最后,打印出原始文本、加密后的文本以及解密后的文本。

请注意,RSA算法适用于加密较小的数据块,因此通常使用对称加密算法来加密大型数据,然后使用RSA算法来加密对称密钥。此示例中仅为演示RSA算法的基本原理而使用了原始文本的加密和解密。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Run,boy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值