Алгоритмы шифрования можно разделить на: обратимое шифрование и необратимое шифрование, а обратимое шифрование можно разделить на: симметричное шифрование и асимметричное шифрование.
1. Необратимое шифрование
Общие алгоритмы необратимого шифрованияMD5
,HMAC
,SHA1
,SHA-224
,SHA-256
,SHA-384
,иSHA-512
,вSHA-224
,SHA-256
,SHA-384
,иSHA-512
мы можем коллективно позвонитьSHA2
алгоритм шифрования,SHA
Алгоритмы шифрования более безопасны, чемMD5
выше, при этомSHA2
отношение алгоритма шифрованияSHA1
выше. вSHA
Следующие числа указывают длину зашифрованной строки,SHA1
По умолчанию160
Сводная информация о битах.
Самой большой особенностью алгоритма необратимого шифрования является ключ, ноHMAC
Это [ручная собачья голова], для которой нужен ключ.
Поскольку эти шифрования необратимы, наиболее часто используемый сценарий — это шифрование пароля пользователя, а процесс проверки заключается в подтверждении личности путем сравнения двух зашифрованных строк. Есть также много онлайн, которые утверждают, что их можно взломать.MD5
Принцип сайта паролей тот же, то есть есть огромная библиотека ресурсов, в которой хранится множество строк и соответствующихMD5
Зашифрованная строка через ваш вводMD5
Зашифрованные строки для сравнения, если сложность вашего пароля относительно невелика, все еще существует высокая вероятность проверки.
1.1 MD5
Алгоритм дайджеста сообщения MD5(английский: MD5 Message-Digest Algorithm), широко используемая криптографическая хеш-функция, которая генерирует 128-битное (16-байтовое) хеш-значение для обеспечения полной и согласованной передачи информации.
MD5
Алгоритм имеет следующие характеристики:
1. Сжимаемость: независимо от длины данных вычисляетсяMD5
Значения имеют одинаковую длину
2. Простота расчета: легко рассчитать по исходным данным.MD5
ценность
3. Устойчивость к модификации: даже если один байт изменен, расчетноеMD5
значения будут сильно различаться
4. Сопротивление столкновениям: знайте данные иMD5
значение, с небольшой вероятностью найти то же самоеMD5
исходные данные с тем же значением.
public static String md5(String text) {
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
byte[] bytes = messageDigest.digest(text.getBytes());
return Hex.encodeHexString(bytes);
}
1.2 Серия ША
Алгоритм безопасного хеширования(англ. Secure Hash Algorithm, сокращенно SHA) — это семейство криптографических хеш-функций и безопасный хеш-алгоритм, сертифицированный FIPS. Алгоритм, который может вычислить строку фиксированной длины (также называемую дайджестом сообщения), соответствующую цифровому сообщению. А если входные сообщения разные, то велика вероятность, что они соответствуют разным строкам.
В конце конференции CRYPTO 17 августа 2005 года Ван Сяоюнь, Яо Цичжи и Яо Чуфэн в очередной раз опубликовали более эффективный метод атаки SHA-1, который может находить коллизии в пределах вычислительной сложности 2 в 63-й степени.
то естьSHA-1
Алгоритмы шифрования имеют возможность коллизий, хотя и небольшую.
public static String sha256(String text) {
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
byte[] bytes = messageDigest.digest(text.getBytes());
return Hex.encodeHexString(bytes);
}
1.3 Серия HMAC
HMAC — это аббревиатура от Hash-based Message Authentication Code (Hash-based Message Authentication Code), относящаяся к ключевому методу аутентификации и опубликованная в 1997 году как RFC2104 иIPSecи другие сетевые протоколы, такие какSSL) широко используется и в настоящее время стал стандартом безопасности в Интернете де-факто. Его можно связать с любой итеративной хэш-функцией.
Алгоритм HMAC больше похож на алгоритм шифрования, который вводит ключ, и его безопасность не полностью зависит от используемого алгоритма хеширования.
public static String hmacSha256(String text, SecretKeySpec sk) {
Mac mac = null;
try {
mac = Mac.getInstance("HmacSHA256");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
mac.init(sk);
} catch (InvalidKeyException e) {
e.printStackTrace();
}
byte[] rawHmac = mac.doFinal(text.getBytes());
return new String(Base64.encodeBase64(rawHmac));
}
Если вы хотите использовать необратимое шифрование, рекомендуется использовать алгоритмы SHA256, SHA384, SHA512 и HMAC-SHA256, HMAC-SHA384, HMAC-SHA512.
2. Алгоритм симметричного шифрования
Алгоритм симметричного шифрования является относительно ранним алгоритмом, и для шифрования и дешифрования данных используется один и тот же ключ, что вызывает проблему сложного управления ключами. Общие алгоритмы симметричного шифрованияDES
,3DES
,AES128
,AES192
,AES256
(устанавливается по умолчаниюJDK
Пока не поддерживаетсяAES256
, необходимо установить соответствующийjce
Патч для обновленияjce1.7
,jce1.8
). вAES
Следующее число представляет длину ключа. Безопасность алгоритма симметричного шифрования относительно низка, и более применимым сценарием является шифрование и дешифрование в среде интрасети.
2.1 DES
DES
является типичным алгоритмом в области алгоритмов симметричного шифрования, а длина ключа по умолчанию равна56
немного.
// 加密
public static String encrypt(byte[] dataSource, String password){
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
//创建一个密匙工厂,然后用它把DESKeySpec转换成
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
//Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
//用密匙初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, secretKey, random);
//正式执行加密操作
return Base64.encodeBase64String(cipher.doFinal(dataSource));
} catch (Throwable e) {
e.printStackTrace();
} return null;
}
// 解密
public static String decrypt(String src, String password) throws Exception{
// DES算法要求有一个可信任的随机数源
SecureRandom random = new SecureRandom();
// 创建一个DESKeySpec对象
DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
// 创建一个密匙工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 将DESKeySpec对象转换成SecretKey对象
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, secretKey, random);
// 真正开始解密操作
return new String(cipher.doFinal(Base64.decodeBase64(src)));
}
2.2 3DES
3DES
(т.е. Тройной DES)DES
В направленииAES
Алгоритм переходного шифрования, использующий три 56-битных ключа для трехкратного шифрования данных. даDES
Более безопасный вариант . это начинается сDES
В качестве базового модуля алгоритм блочного шифрования разработан путем комбинирования метода группировки. чем оригиналDES
,3DES
Безопаснее. Длина ключа по умолчанию равна168
бит, вы также можете выбрать128
немного.
public static String encryptThreeDESECB(String src, String key) {
try{
DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey securekey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, securekey);
byte[] b = cipher.doFinal(src.getBytes("UTF-8"));
String ss = new String(Base64.encodeBase64(b));
ss = ss.replaceAll("\\+", "-");
ss = ss.replaceAll("/", "_");
return ss;
} catch(Exception ex){
ex.printStackTrace();
return src;
}
}
public static String decryptThreeDESECB(String src, String key) {
try{
src = src.replaceAll("-", "+");
src = src.replaceAll("_", "/");
byte[] bytesrc = Base64.decodeBase64(src.getBytes("UTF-8"));
// --解密的key
DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey securekey = keyFactory.generateSecret(dks);
// --Chipher对象解密
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, securekey);
byte[] retByte = cipher.doFinal(bytesrc);
return new String(retByte, "UTF-8");
} catch(Exception ex){
ex.printStackTrace();
return src;
}
}
2.3 AES
AES
Усовершенствованный стандарт шифрования данных, эффективный против известныхDES
Все атаки на алгоритм, длина ключа по умолчанию128
биты, также по желанию192
немного,256
немного. Здесь, кстати, этот бит относится к биту.
private static final String defaultCharset = "UTF-8";
private static final String KEY_AES = "AES";
private static final String KEY_MD5 = "MD5";
private static MessageDigest md5Digest;
static {
try {
md5Digest = MessageDigest.getInstance(KEY_MD5);
} catch (NoSuchAlgorithmException e) {
}
}
/**
* 加密
*/
public static String encrypt(String data, String key) {
return doAES(data, key, Cipher.ENCRYPT_MODE);
}
/**
* 解密
*/
public static String decrypt(String data, String key) {
return doAES(data, key, Cipher.DECRYPT_MODE);
}
/**
* 加解密
*/
private static String doAES(String data, String key, int mode) {
try {
boolean encrypt = mode == Cipher.ENCRYPT_MODE;
byte[] content;
if (encrypt) {
content = data.getBytes(defaultCharset);
} else {
content = Base64.decodeBase64(data.getBytes());
}
SecretKeySpec keySpec = new SecretKeySpec(md5Digest.digest(key.getBytes(defaultCharset))
, KEY_AES);
Cipher cipher = Cipher.getInstance(KEY_AES);// 创建密码器
cipher.init(mode, keySpec);// 初始化
byte[] result = cipher.doFinal(content);
if (encrypt) {
return new String(Base64.encodeBase64(result));
} else {
return new String(result, defaultCharset);
}
} catch (Exception e) {
}
return null;
}
Рекомендуемые алгоритмы симметричного шифрования:AES128
,AES192
,AES256
.
3. Алгоритм асимметричного шифрования
Алгоритмы асимметричного шифрования имеют два ключа, которые совершенно разные, но точно совпадают. Шифрование и дешифрование открытого текста может быть выполнено только с использованием совпадающей пары открытого и закрытого ключей. Обычные асимметричные шифрыRSA
,SM2
Ждать.
3.1 RSA
RSA
Ключ должен иметь длину не менее 500 бит, обычно рекомендуется 1024 бита.
//非对称密钥算法
public static final String KEY_ALGORITHM = "RSA";
/**
* 密钥长度,DH算法的默认密钥长度是1024
* 密钥长度必须是64的倍数,在512到65536位之间
*/
private static final int KEY_SIZE = 1024;
//公钥
private static final String PUBLIC_KEY = "RSAPublicKey";
//私钥
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* 初始化密钥对
*
* @return Map 甲方密钥的Map
*/
public static Map<String, Object> initKey() throws Exception {
//实例化密钥生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
//初始化密钥生成器
keyPairGenerator.initialize(KEY_SIZE);
//生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//甲方公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
//甲方私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
//将密钥存储在map中
Map<String, Object> keyMap = new HashMap<String, Object>();
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 私钥加密
*
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密数据
*/
public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
//取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
//数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 公钥加密
*
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密数据
*/
public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {
//实例化密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//初始化公钥
//密钥材料转换
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
//产生公钥
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
//数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return cipher.doFinal(data);
}
/**
* 私钥解密
*
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密数据
*/
public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
//取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
//数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 公钥解密
*
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密数据
*/
public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {
//实例化密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//初始化公钥
//密钥材料转换
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
//产生公钥
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
//数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, pubKey);
return cipher.doFinal(data);
}
/**
* 取得私钥
*
* @param keyMap 密钥map
* @return byte[] 私钥
*/
public static byte[] getPrivateKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return key.getEncoded();
}
/**
* 取得公钥
*
* @param keyMap 密钥map
* @return byte[] 公钥
*/
public static byte[] getPublicKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key.getEncoded();
}
В-четвертых, шифровальная соль
Также часто можно услышать понятие «соль шифрования».Соль — это случайная строка, используемая для ее шифрования после сращивания с нашей зашифрованной строкой. Основная цель добавления соли — обеспечить безопасность зашифрованных строк. Если имеется зашифрованная строка с солью, и хакер использует эту зашифрованную строку определенным образом, открытый текст, который он получает, представляет собой не строку до шифрования, а строку, объединенную со строкой до шифрования и солью. строка снова.
Некоторые алгоритмы в этой статье получены из сети и могут быть напрямую скопированы и использованы..
Несколько рекомендуемых алгоритмов шифрования:
- Необратимое шифрование:
SHA256
,SHA384
,SHA512
а такжеHMAC-SHA256
,HMAC-SHA384
,HMAC-SHA512
- Алгоритм симметричного шифрования:
AES
,3DES
- Алгоритм асимметричного шифрования:
RSA