当前,我们正在加密用户从登录页面输入的密码,并将其存储在数据库中。这里正在开发一个新的登录页面以供内部使用,并重复使用相同的用户名和加密密码。如果用户被授权,则将允许他访问报告。在这里,我的问题是,我该如何获取他们用来加密的密钥。想要使用相同的密钥来解密密码,那么我可以继续我的逻辑。
这是我们用来加密密码的代码。
user = userRemote.loginUser(userName, new String(EncryptDecrypt.storePassword(password),"Cp1252"));
Here password is Password entered in the login page.
这是加密密码的方法。
final static byte[] salt = {
(byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
(byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
};
final static int count = 1;
public static byte[] storePassword(char[] password) throws InternalException {
PBEKeySpec pbeKeySpec;
PBEParameterSpec pbeParamSpec;
SecretKeyFactory keyFac;
byte[] ciphertext = null;
try {
// Install SunJCE provider
Provider sunJce = new com.sun.crypto.provider.SunJCE();
Security.addProvider(sunJce);
// Create PBE parameter set
pbeParamSpec = new PBEParameterSpec(salt, count);
pbeKeySpec = new PBEKeySpec(password);
keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
// Create PBE Cipher
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
// Initialize PBE Cipher with key and parameters
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
// Our cleartext
byte[] cleartext = (new String(password)).getBytes("Cp1252");
// Encrypt the cleartext
ciphertext = pbeCipher.doFinal(cleartext);
} catch (BadPaddingException ex) {
log.error("EncryptDecrypt: " + ex.getMessage());
throw new InternalException(ex.getMessage());
} catch (Exception ex) {
log.error("EncryptDecrypt: " + ex.getMessage());
throw new InternalException(ex.getMessage());
}
return ciphertext;
}
这是用于解密密码的类。在这里,我只有加密的密码作为解密密码的输入。例如•Ä0BÒO,因此要使用它来生成密钥并对其进行解密。但是,低于例外。 java.security.spec.InvalidKeySpecException:密码不是ASCII
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class DecryptPassword {
public static void main(String[] args) {
String decryptedStr = checkPassword("•Ä0BÒ¦O");
System.out.println("decryptedStr : "+decryptedStr);
}
final static byte[] salt = {
(byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
(byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
};
final static int count = 1;
static String decryptedPassword = "";
public static String checkPassword(String encryptedPassword) {
PBEKeySpec pbeKeySpec;
PBEParameterSpec pbeParamSpec;
SecretKeyFactory keyFac;
try {
// Install SunJCE provider
Provider sunJce = new com.sun.crypto.provider.SunJCE();
Security.addProvider(sunJce);
// Create PBE parameter set
pbeParamSpec = new PBEParameterSpec(salt, count);
pbeKeySpec = new PBEKeySpec(encryptedPassword.toCharArray());
keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
// Create PBE Cipher
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
// Initialize PBE Cipher with key and parameters
pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec);
byte[] decrypted = pbeCipher.doFinal(encryptedPassword.getBytes());
decryptedPassword = decrypted.toString();
} catch (BadPaddingException ex) {
System.out.println("EncryptDecrypt: " + ex.getMessage());
} catch (Exception ex) {
System.out.println("EncryptDecrypt: " + ex.getMessage());
}
return decryptedPassword;
}
}
这里我应该能够成功解密密码,但是不能解密。有人可以帮助我这里缺少什么吗?提前谢谢。
答案 0 :(得分:2)
这不是加密,是哈希!(边缘快照)
storePassword
例程有效地使用密码进行自我加密;更确切地说,PBEwithMD5andDES
使用原始PKCS5v1派生函数从密码派生的密钥(为清楚起见,现在重新命名为PBKDF1),并以MD5,固定盐和1(!)迭代实例化,以原始DES CBC加密密码。这是以前流行的创建加密哈希的方式的变体。
在1960年代和1970年代,也许是1980年代,在密码学家将注意力转移到设计特定的密码哈希函数之前,密码是唯一的密码基元,一种将密码(键排列)转换为密码哈希(非键)的常用方法。函数)是将数据用作加密常量的键;对此的一个细微变化是作为库函数实现的,其名称错误地命名为crypt
,并在1970年左右被用作the password hashing function in early Unix,至今仍被记住(有时甚至被使用),但现在经常被追溯为DES-crypt
或{{ 1}},以区别于此后开发的替代方案和替代方案。
与旨在被解密的密码不同,这是一个散列,并且不可逆。我不知道有什么方法可以比蛮力更容易地扭转这种方法(即分析性的“断裂”),但是原始的DES,现在通常称为单DES(或1DES),以区别于其直接后继三元DES(或3DES或正式的TDEA)足够脆弱,如果您真的愿意的话,现在可以将其强行使用。例如,单盐解密的JTR reports大约为10M-30M次/秒,对于简单的DES大约为0.5G /秒,因此在一台计算机上尝试所有DES密钥将花费数年,而使用一台计算机则需要数天。一千台计算机,或者几分钟内有一百万台计算机。关于hashcat的数据较难找到,但看起来大致可比。如果您知道如何选择密码,那么尝试仅使用可能的密码而不是所有可能的密钥可能会更快。
但是不要。 验证密码哈希的正确方法是让用户提供要求保护的密码,并使用相同的参数重复哈希过程(此处很简单,因为它没有使用可变的salt),并查看新的哈希结果是否与存储的结果相符。