我已经创建了一个项目。
在此,他们使用一种方法来加密String。 在这个项目中,我现在必须创建一个方法,我可以用它来解密加密的字符串。
对于加密字符串,使用以下方法
private String EncryptPwd(String pwd) {
String encryptPwd = "";
if (!pwd.isEmpty()) {
byte[] sha1Bytes = EncryptionUtils.getSha1(pwd);
StringBuilder sb = new StringBuilder();
for (byte b : sha1Bytes) {
sb.append(b);
}
encryptPwd = sb.toString();
}
return encryptPwd;
}
下面给出了EncryptionUtils类代码
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.log4j.Logger;
public final class EncryptionUtils {
private static QueueCacheValueCloner<byte[]> byteArrayCloner = new QueueCacheValueCloner() {
public byte[] cloneBean(byte[] original) {
return (byte[]) original.clone();
}
};
private static Logger logger = MiscUtils.getLogger();
private static final MessageDigest messageDigest = initMessageDigest();
private static final QueueCache<String, byte[]> sha1Cache = new QueueCache(4, 2048, byteArrayCloner);
private static final int MAX_SHA_KEY_CACHE_SIZE = 2048;
private static MessageDigest initMessageDigest() {
try {
return MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
logger.error("Error", e);
}
return null;
}
public static byte[] getSha1(String s) {
byte[] b = (byte[]) sha1Cache.get(s);
if (b == null) {
b = getSha1NoCache(s);
if (s.length() < 2048) {
sha1Cache.put(s, b);
}
}
return b;
}
protected static byte[] getSha1NoCache(String s) {
}
public static SecretKey generateEncryptionKey() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
return secretKey;
}
public static SecretKeySpec generateEncryptionKey(String seed) {
byte[] sha1 = getSha1(seed);
SecretKeySpec secretKey = new SecretKeySpec(sha1, 0, 16, "AES");
return secretKey;
}
public static byte[] encrypt(SecretKey secretKey, byte[] plainData) throws IllegalBlockSizeException,
BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
if (secretKey == null) {
return plainData;
}
Cipher cipher = Cipher.getInstance("AES");
cipher.init(1, secretKey);
byte[] results = cipher.doFinal(plainData);
return results;
}
public static byte[] decrypt(SecretKey secretKey, byte[] encryptedData) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
if (secretKey == null) {
return encryptedData;
}
Cipher cipher = Cipher.getInstance("AES");
cipher.init(2, secretKey);
byte[] results = cipher.doFinal(encryptedData);
return results;
}
}
现在我必须创建一个解密加密字符串的方法。
所以有人可以建议我如何解密由上述EncryptPwd
方法加密的字符串。
答案 0 :(得分:2)
哈希不是加密。安全散列是一种单向函数,可以创建一定长度的输出,无法与随机区分到不知道原始输入的攻击者。
&#34;反转&#34;的唯一方法哈希是测试所有可能的输入值。如果找到正确的哈希值,那么您就找到了输入,因为在计算上不可能找到两条生成相同输出值的消息。至少,在Google找到使用 Shattered 攻击创建所谓的SHA-1冲突的方法之前,情况就是如此。但是,这对通常具有大小和格式限制的密码等字符串没有任何影响。
使用SHA-1对密码进行哈希处理会使自己容易受到彩虹表攻击。也可以轻松识别重复密码(如果有多个帐户)。缓存结果还会使您的密码表容易受到简单的计时攻击。只是使用真正的密码哈希,例如Argon2,并且需要特定的密码强度是一个好主意。
验证密码哈希的方法是从给定密码(盐和工作因子)开始执行相同的计算,然后比较结果。解密并没有进入它。
答案 1 :(得分:1)
SHA1是一种哈希函数,其设计方式使您无法解密任何加密的#34; (实际上它没有被加密 - 它只是消息的散列 - 正如评论中所建议的)(因为它的定向功能)
相反,您可以在系统中存储SHA签名(非原始密码)并比较签名(如果您知道如何生成它)。
这样做的好处是没有人知道密码(用户除外),你仍然可以验证他是否正确输入了密码(你只知道如何从用户输入生成SHA,但不以纯文本形式存储他的密码)< / p>