常用加密算法笔记
来源:互联网 发布:阿里云个人邮箱下载 编辑:程序博客网 时间:2024/06/05 06:18
一、对称性加密算法
1.概述
DES(Data Encryption Standard):数字签名算法,速度较快,适用于大量数据加密
3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。
AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高
密钥长度
运算速度
安全性
资源消耗
DES
56位
较快
低
中
3DES
112位或168位
慢
中
高
AES
128、192、256位
快
高
低
2.java代码的实现
DES:下面这种实现密钥长度要大于8位
import java.security.InvalidKeyException;import java.security.Key;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.security.spec.InvalidKeySpecException;import javax.crypto.Cipher;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;import org.apache.commons.codec.binary.Base64;public class DESTool { //算法名称/加密模式/填充方式 //DES共有四种工作模式-->>ECB:电子密码本模式、CBC:加密分组链接模式、CFB:加密反馈模式、OFB:输出反馈模式 public static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding"; /** * * 生成密钥key对象 * @param KeyStr 密钥字符串 * @return 密钥对象 * @throws InvalidKeyException * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws Exception */ private static SecretKey keyGenerator(String keyStr) throws Exception { DESKeySpec desKey = new DESKeySpec(keyStr.getBytes()); //创建一个密匙工厂,然后用它把DESKeySpec转换成 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey securekey = keyFactory.generateSecret(desKey); return securekey; }/** * 加密数据 * @param data 待加密数据 * @param key 密钥 * @return 加密后的数据 */ public static String encrypt(String data, String key) throws Exception { Key deskey = keyGenerator(key); // 实例化Cipher对象,它用于完成实际的加密操作 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); SecureRandom random = new SecureRandom(); // 初始化Cipher对象,设置为加密模式 cipher.init(Cipher.ENCRYPT_MODE, deskey, random); byte[] results = cipher.doFinal(data.getBytes()); // 执行加密操作。加密后的结果通常都会用Base64编码进行传输 return Base64.encodeBase64String(results); } /** * 解密数据 * @param data 待解密数据 * @param key 密钥 * @return 解密后的数据 */ public static String decrypt(String data, String key) throws Exception { Key deskey = keyGenerator(key); Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); //初始化Cipher对象,设置为解密模式 cipher.init(Cipher.DECRYPT_MODE, deskey); // 执行解密操作 return new String(cipher.doFinal(Base64.decodeBase64(data))); } }AES:
import java.security.SecureRandom;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import org.apache.commons.codec.binary.Base64;public class AESTool {/** * 加密 * * @param content * 需要加密的内容 * @param password * 加密密码 * @return */public static String encrypt(String content, String password) {try {KeyGenerator kgen = KeyGenerator.getInstance("AES");kgen.init(128, new SecureRandom(password.getBytes()));SecretKey secretKey = kgen.generateKey();byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");Cipher cipher = Cipher.getInstance("AES");// 创建密码器byte[] byteContent = content.getBytes("utf-8");cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化byte[] result = cipher.doFinal(byteContent);return Base64.encodeBase64String(result);// 加密} catch (Exception e) {e.printStackTrace();}return null;}/** * 解密 * * @param content * 待解密内容 * @param password * 解密密钥 * @return */public static String decrypt(String content, String password) {try {KeyGenerator kgen = KeyGenerator.getInstance("AES");kgen.init(128, new SecureRandom(password.getBytes()));SecretKey secretKey = kgen.generateKey();byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");Cipher cipher = Cipher.getInstance("AES");// 创建密码器cipher.init(Cipher.DECRYPT_MODE, key);// 初始化byte[] result = cipher.doFinal(Base64.decodeBase64(content));return new String(result); // 加密} catch (Exception e) {e.printStackTrace();}return null;}}
二、非对称加密算法
1.概述
加密密钥和解密密钥不同
RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的;
DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准);
成熟度
安全性(取决于密钥长度)
运算速度
资源消耗
RSA
高
高
慢
高
DSA
高
高
慢
只能用于数字签名
2.java代码的实现
RSA:可用于加密和签名
import java.security.Key;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;import javax.crypto.Cipher;import org.apache.commons.codec.binary.Base64;public class RSATool {public static final String PUBLIC_KEY = "RSAPublicKey";//公钥public static final String PRIVATE_KEY = "RSAPrivateKey";//私钥/** * 初始化密钥 * @return * @throws Exception */public static Map<String,Key> initKey()throws Exception{KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(1024);KeyPair keyPair = keyPairGenerator.generateKeyPair();//公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();Map<String,Key> keyMap = new HashMap<String,Key>(2);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;} /** * 用公钥加密 * @param data加密数据 * @param key密钥 * @return * @throws Exception */public static String encryptByPublicKey(String data,Key key)throws Exception{//取公钥X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key.getEncoded());KeyFactory keyFactory = KeyFactory.getInstance("RSA");//指定加密算法Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);//对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] results =cipher.doFinal(data.getBytes());return Base64.encodeBase64String(results);} /** * 用私钥解密 * @param data 加密数据 * @param key密钥 * @return * @throws Exception */public static String decryptByPrivateKey(String data,Key key)throws Exception{//取私钥PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key.getEncoded());KeyFactory keyFactory = KeyFactory.getInstance("RSA");//指定加密算法Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);//对数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] results =cipher.doFinal(Base64.decodeBase64(data));return new String(results);}/** *用私钥对信息生成数字签名 * @param data原数据 * @param privateKey 私钥 * @return * @throws Exception */public static String sign(String data,Key privateKey)throws Exception{//取私钥PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());KeyFactory keyFactory = KeyFactory.getInstance("RSA");//指定加密算法PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);//用私钥对信息生成数字签名Signature signature = Signature.getInstance("MD5withRSA");signature.initSign(privateKey2);signature.update(data.getBytes());return Base64.encodeBase64String(signature.sign());}/** * 公钥校验数字签名 * @param data加密数据 * @param publicKey公钥 * @param sign数字签名 * @return * @throws Exception */public static boolean verify(String data,Key publicKey,String sign)throws Exception{//取公钥X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);Signature signature = Signature.getInstance("MD5withRSA");signature.initVerify(publicKey2);signature.update(data.getBytes());//验证签名是否正常return signature.verify(Base64.decodeBase64(sign));} }DSA:代码跟RSA算法一样,只需把获得算法参数改成DSA.另DSA只能用于签名
三、散列算法
1.概述
这种算法只生成一串不可逆的密文
MD5(Message Digest Algorithm 5):是RSA数据安全公司开发的一种单向散列算法,非可逆,相同的明文产生相同的密文。
SHA-1(Secure Hash Algorithm):安全度相对高;
2.java代码的实现
private static String sha1X16(String data) throws Exception{try {MessageDigest md = MessageDigest.getInstance("SHA-1");md.reset();md.update(data.getBytes("utf-8"));byte[] bytes =md.digest();//转16进制StringBuilder sha1StrBuff = new StringBuilder();for (int i = 0; i < bytes.length; ++i){if (Integer.toHexString(0xFF & bytes[i]).length() == 1) {sha1StrBuff.append("0").append(Integer.toHexString(0xFF & bytes[i]));} elsesha1StrBuff.append(Integer.toHexString(0xFF & bytes[i]));} return sha1StrBuff.toString().toLowerCase();} catch (Exception e) {throw e;}}
四、密钥证书
1、常见证书格式
.pfx/.p12 PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形式。
.cer/.crt是用于存放证书,它是DER 编码(ASCII)的2进制形式存放的,不含私钥。
.pem是用于存放证书,它是BASE64 编码的2进制形式存放的,不含私钥。
2、java代码实现
.pfx格式:获得公钥和私钥
import java.io.FileInputStream;import java.io.IOException;import java.security.KeyStore;import java.security.PrivateKey;import java.security.PublicKey;import java.security.cert.Certificate;import java.util.Enumeration;public class CerTool {public static final String KEYSTORE_FILE = "D:/test.pfx";public static final String KEYSTORE_PASSWORD = "111111";public static void main(String[] args) {FileInputStream fis = null;try {// 获得KeyStoreKeyStore ks = KeyStore.getInstance("PKCS12");fis = new FileInputStream(KEYSTORE_FILE);char[] nPassword = KEYSTORE_PASSWORD.toCharArray();ks.load(fis, nPassword);// 根据条目获得私钥Enumeration aliasenum = ks.aliases();String keyAlias = null;if (aliasenum.hasMoreElements()) {keyAlias = (String) aliasenum.nextElement();}PrivateKey priKey = (PrivateKey) ks.getKey(keyAlias,KEYSTORE_PASSWORD.toCharArray());// 根据条目获得公钥Certificate cert = ks.getCertificate(keyAlias);PublicKey pubkey = cert.getPublicKey();//使用RSA测试String content="hello";String en=RSATool.encryptByPublicKey(content,pubkey);System.out.println(en);System.out.println(RSATool.decryptByPrivateKey(en,priKey));} catch (Exception e) {e.printStackTrace();} finally {try {if (fis != null) {fis.close();}} catch (IOException e) {e.printStackTrace();}}}}.cer格式:获得公钥
public PublicKey getPublic() {InputStream in = null;try {//引用于java.security.certCertificateFactory cf = CertificateFactory.getInstance("X.509");in = new FileInputStream("D:/test.cer");X509Certificate verifyCert = (X509Certificate) cf.generateCertificate(in);PublicKey publicKey = verifyCert.getPublicKey();return publicKey;} catch (Exception e) {e.printStackTrace();} finally {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}}return null;}
五、算法的选择
由于非对称加密算法的运行速度比对称加密算法的速度慢很多,当我们需要加密大量的数据时,建议采用对称加密算法,提高加解密速度。
对称加密算法不能实现签名,因此签名只能非对称算法。
由于对称加密算法的密钥管理是一个复杂的过程,密钥的管理直接决定着他的安全性,因此当数据量很小时,我们可以考虑采用非对称加密算法。
在实际的操作过程中,我们通常采用的方式是:采用非对称加密算法管理对称算法的密钥,然后用对称加密算法加密数据,这样我们就集成了两类加密算法的优点,既实现了加密速度快的优点,又实现了安全方便管理密钥的优点。
那采用多少位的密钥呢? RSA建议采用1024位的数字,ECC建议采用160位,AES采用128为即可。
ps:数字签名和加密的区别
数字签名的作用一是保证数据的完整性,二是对发送者进行身份认证。所以它是采用非对称算法,消息发送者使用私钥加密,接收者使用公钥解密验签;
加密重点在于“数据的安全性”,可以防止数据被监听攻击。所以消息发送者采用公钥加密,只有拥有私钥的接收者才能解密;
- 常用加密算法笔记
- 密码学笔记1-基本概念和常用加密算法
- 常用加密算法
- 常用加密算法
- 常用加密算法
- 常用加密算法
- 常用加密算法
- 常用加密算法
- 常用加密算法
- 常用加密算法
- 常用加密算法
- 常用加密算法
- 常用加密算法
- 加密算法笔记
- .Net 常用加密算法类
- .Net 常用加密算法类
- .Net 常用加密算法类
- .Net 常用加密算法类
- 关于SQL连接语句中的Integrated Security=SSPI/ture/false
- REST架构风格的由来&元素
- 自定义CircularProgressBar
- 彻底理解android中的内部存储与外部存储
- [golang] struct转JSON,解析JSON
- 常用加密算法笔记
- RecyclerView封装
- 2.8 Git 基础 - 总结
- Android中OrmLite数据库使用总结
- 持续集成之代码质量管理-Sonar [三]
- 如何搜索
- LeetCode 27---Remove Element
- log4j2.xml<Console name="Console" target="SYSTEM_OUT">
- OpenStack官方操作指南(1)架构样例