gpt4 book ai didi

Java RSA 为什么每次都有不同的密文?

转载 作者:行者123 更新时间:2023-11-28 23:45:58 27 4
gpt4 key购买 nike

我正在使用 JSP/Servlets/MySQL 和 RSA 算法开发一个登录模块。注册新用户后,我将 PublicKey 保存到 MySQL 中并用它加密密码。

当用户尝试登录时,我检索该 PublicKey 并使用相应的 PublicKey 加密刚刚输入的密码,并将其与之前保存的加密密码进行比较,但它总是返回不同的密文。

我想不通为什么每次都得到不同的加密密码。我做错了什么吗?它会在每次运行“keyFactory.generatePublic”时生成一个新的 PublicKey 吗?

谢谢你的帮助

我生成公钥的方法是:

    public byte[] generateBytePublicKey() throws Exception {
byte[] pk = null;

try {
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
keyGen.initialize(1024);
pk = keyGen.generateKeyPair().getPublic().getEncoded();
} (...... etc etc)
return pk;

我加密密码的方法:

    public byte[] encryptBytes(String pwd, byte[] key) throws Exception {

byte[] cipherText = null;
PublicKey pk;

try {
byte[] dataBytes = pwd.getBytes();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
pk = keyFactory.generatePublic(new X509EncodedKeySpec(key));
final Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pk);
cipherText = cipher.doFinal(dataBytes);
} (..... etc etc)
return cipherText;

我将加密的密码和公钥存储到 MySQL 表中的方法:

    (.....................)
try {
Statement stmt = null;
ResultSet rs = null;
byte[] bytePublicKey;
byte[] cipherPwd;

bytePublicKey = generateBytePublicKey();
cipherPwd = encryptBytes(password, bytePublicKey);

String query = "INSERT INTO Users (email, pwd, publickey) VALUES ('" + email + "', ?, ?)";
PreparedStatement ps;
ps = conn.getConexion().prepareStatement(query);
ps.setBytes(1, cipherPwd);
ps.setBytes(2, bytePublicKey);
resultSet = ps.executeUpdate();
} (............. etc etc)

我检查用户是否有效的方法:

   public boolean isUserValid (String email, String typedPassword) throws Exception {

byte[] storedBytesPassword;
byte[] storedBytesPublicKey;
byte[] typedPwdtoBytes;

try {
storedBytesPublicKey = getByteArrays(email, "publicKey");
storedBytesPassword = getByteArrays(email, "pwd");

typedPwdtoBytes = encryptBytes(typedPassword, storedBytesPublicKey);

return Arrays.equals(typedPwdtoBytes, storedBytesPassword);
} (............. etc etc)

我从 MySQL 表中获取字节数组的方法:

  public byte[] getByteArrays (String email, String byteArray) throws SQLException {

(..............)

try {
Statement stmt=null;
ResultSet rs=null;

query = "SELECT " + byteArray + " FROM Users WHERE email = '" + email + "'";

try {
stmt = (conn.getConexion()).createStatement();
rs = stmt.executeQuery(query);
while (rs.next() ) {
bytesArr = rs.getBytes(1);
} (.................. etc etc)

最佳答案

当您未指定完整转换时,您将获得提供程序默认值,对于 RSA,这可能是 RSA/ECB/PKCS1Padding

PKCS1Padding(见Padding schemes)表示加入随机数据,保证对同一个明文加密两次会产生不同的密文。

密码用于加密和解密。由于您不打算解密密码,因此密码不是您的正确选择。

对于单向“加密”,使用 message digest , 也称为 Cryptographic hash function .它们通过生成明文的散列/摘要来像 Java hashCode() 方法一样工作,但与 hashCode() 不同,摘要要复杂得多,以确保无法从摘要值推断出明文。

由于它是一种单向算法,您可以将 key 和摘要值存储在一起。摘要的目的是确保您始终从相同的明文/ key 组合中获得相同的摘要值。

您甚至可以对所有密码使用相同的 key 。请记住,它是不可逆的,只要摘要算法足够强大,例如SHA-256

关于Java RSA 为什么每次都有不同的密文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33579782/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com