密码学基础
介绍
密码学是研究如何安全地传输和存储信息的科学。它涉及加密和解密技术,用于保护信息不被未授权的访问和修改。在信息安全中,密码学是实现保密性、完整性和不可否认性的核心技术。
核心概念与原理
密码学基本术语
- 明文(Plaintext):未加密的原始信息
- 密文(Ciphertext):加密后的信息
- 密钥(Key):用于加密和解密的参数
- 加密(Encryption):将明文转换为密文的过程
- 解密(Decryption):将密文转换为明文的过程
- 密码算法(Cipher Algorithm):用于加密和解密的数学函数
密码学分类
- 对称密码学(Symmetric Cryptography):加密和解密使用相同密钥的密码学
- 非对称密码学(Asymmetric Cryptography):加密和解密使用不同密钥的密码学
- 哈希函数(Hash Function):将任意长度的输入转换为固定长度输出的函数
密码学模型图示
+----------------+ +----------------+ +----------------+
| 对称密码学 | | 非对称密码学 | | 哈希函数 |
+----------------+ +----------------+ +----------------+
| - 相同密钥 | | - 公钥/私钥对 | | - 固定长度输出 |
| - 速度快 | | - 速度较慢 | | - 单向函数 |
| - DES, AES | | - RSA, ECC | | - SHA, MD5 |
+----------------+ +----------------+ +----------------+
对称密码学
流密码与分组密码
- 流密码(Stream Cipher):逐位加密明文
- 分组密码(Block Cipher):将明文分成固定长度的块进行加密
常见对称加密算法
AES(高级加密标准)
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class AESExample {
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
public static String encrypt(String plaintext, String key) throws Exception {
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decrypt(String ciphertext, String key) throws Exception {
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decodedBytes = Base64.getDecoder().decode(ciphertext);
byte[] decryptedBytes = cipher.doFinal(decodedBytes);
return new String(decryptedBytes);
}
}
非对称密码学
公钥基础设施(PKI)
- 公钥(Public Key):公开的密钥,用于加密信息
- 私钥(Private Key):保密的密钥,用于解密信息
- 证书(Certificate):证明公钥与实体身份关联的数字文件
- 证书颁发机构(CA):颁发和管理证书的机构
常见非对称加密算法
RSA算法
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import javax.crypto.Cipher;
public class RSAExample {
private static final String ALGORITHM = "RSA";
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
keyPairGenerator.initialize(2048);
return keyPairGenerator.generateKeyPair();
}
public static String encrypt(String plaintext, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decrypt(String ciphertext, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decodedBytes = Base64.getDecoder().decode(ciphertext);
byte[] decryptedBytes = cipher.doFinal(decodedBytes);
return new String(decryptedBytes);
}
}
哈希函数
特性
- 单向性:无法从哈希值推导出原始输入
- 抗碰撞性:很难找到两个不同的输入产生相同的哈希值
- 固定长度输出:无论输入长度如何,输出长度固定
常见哈希算法
SHA-256
import java.security.MessageDigest;
import java.util.HexFormat;
public class SHA256Example {
public static String hash(String input) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = messageDigest.digest(input.getBytes());
return HexFormat.of().formatHex(hashBytes);
}
}
数字签名
原理
- 发送方使用私钥对消息进行签名
- 接收方使用发送方的公钥验证签名
数字签名示例
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.Base64;
public class DigitalSignatureExample {
private static final String ALGORITHM = "SHA256withRSA";
public static String sign(String message, PrivateKey privateKey) throws Exception {
Signature signature = Signature.getInstance(ALGORITHM);
signature.initSign(privateKey);
signature.update(message.getBytes());
byte[] signatureBytes = signature.sign();
return Base64.getEncoder().encodeToString(signatureBytes);
}
public static boolean verify(String message, String signature, PublicKey publicKey) throws Exception {
Signature sig = Signature.getInstance(ALGORITHM);
sig.initVerify(publicKey);
sig.update(message.getBytes());
byte[] signatureBytes = Base64.getDecoder().decode(signature);
return sig.verify(signatureBytes);
}
}
解决方案
密码学应用场景
- 数据加密:保护敏感数据的传输和存储
- 身份认证:验证用户或系统的身份
- 数据完整性验证:确保数据在传输和存储过程中不被修改
- 不可否认性:确保用户无法否认其已执行的操作
- 密钥交换:安全地交换加密密钥
密码学最佳实践
- 使用强密码算法:避免使用已被破解或弱的密码算法
- 保护密钥:确保密钥的安全存储和管理
- 定期更换密钥:定期更换加密密钥,减少密钥泄露的风险
- 使用合适的密钥长度:根据安全需求选择合适的密钥长度
- 避免硬编码密钥:不要在代码中硬编码密钥
工具推荐
- OpenSSL:开源加密工具包
- Bouncy Castle:Java加密库
- Crypto++:C++加密库
- HashiCorp Vault:密钥管理工具
- Keycloak:开源身份和访问管理解决方案