如何根据密码和盐创建javax.crypto.secretkey

发布于 2025-02-13 04:32:38 字数 2606 浏览 0 评论 0原文

我不是安全专家。

我需要基于passwordsalt生成javax.crypto.crypto.secretkey

在现有代码中,我们已经有逻辑可以生成javax.crypto.secretkey,但不能基于password和 salt“。

另外,在现有代码中,我们已经使用javax.crypto.secretkey进行了加密和解密。 DB中已经有很多数据使用现有加密代码进行了加密,我认为我无法更改现有的加密和解密逻辑。

当我尝试使用基于passwordsalt使用现有解密代码生成的键解密数据时,我会低于错误。

key.getAlgorithm(): DESede
encryptedData: [B@31dc339b
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
    at com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:975)
    at com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1056)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
    at com.sun.crypto.provider.DESedeCipher.engineDoFinal(DESedeCipher.java:294)
    at javax.crypto.Cipher.doFinal(Cipher.java:2168)
    at com.arjun.mytest.PMAdminKeyTest.main(PMAdminKeyTest.java:41)

import java.security.KeyStore;
import java.security.Provider;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class PMAdminKeyTest {

    public static void main(String[] args) throws Exception {
        // Requirement is to generate Key based on password and salt
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec keySpec = new PBEKeySpec("password".toCharArray(), "salt".getBytes(), 65536, 192);
        SecretKey key = new SecretKeySpec(secretKeyFactory.generateSecret(keySpec).getEncoded(), "DESede");

        System.out.println("key.getAlgorithm(): " + key.getAlgorithm());

        byte[] data = "12345678".getBytes("UTF8");

        // Existing encrypt and decrypt code. There is already lot of data in DB
        // encrypted in this manner. I dont think I can change this code.
        Cipher cipher = Cipher.getInstance(key.getAlgorithm() + "/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedData = cipher.doFinal(data);

        System.out.println("encryptedData: " + encryptedData.toString());

        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decryptedData = cipher.doFinal(data);

        System.out.println("decryptedData: " + decryptedData.toString());
    }

}

I am not a security expert.

I have a requirement to generate javax.crypto.SecretKey based on password and salt.

In the existing code, we already have logic to generate javax.crypto.SecretKey but not based on password andsalt`.

Also, in the existing code we already encrypt and decrypt using the javax.crypto.SecretKey.
There is already lot of data in DB which is encrypted using existing encrypt code and I dont think I can change existing encrypt and decrypt logic.

I am getting below the error when I try to decrypt data using the key generated based on password and salt with existing decrypt code.

key.getAlgorithm(): DESede
encryptedData: [B@31dc339b
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
    at com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:975)
    at com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1056)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
    at com.sun.crypto.provider.DESedeCipher.engineDoFinal(DESedeCipher.java:294)
    at javax.crypto.Cipher.doFinal(Cipher.java:2168)
    at com.arjun.mytest.PMAdminKeyTest.main(PMAdminKeyTest.java:41)

import java.security.KeyStore;
import java.security.Provider;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class PMAdminKeyTest {

    public static void main(String[] args) throws Exception {
        // Requirement is to generate Key based on password and salt
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec keySpec = new PBEKeySpec("password".toCharArray(), "salt".getBytes(), 65536, 192);
        SecretKey key = new SecretKeySpec(secretKeyFactory.generateSecret(keySpec).getEncoded(), "DESede");

        System.out.println("key.getAlgorithm(): " + key.getAlgorithm());

        byte[] data = "12345678".getBytes("UTF8");

        // Existing encrypt and decrypt code. There is already lot of data in DB
        // encrypted in this manner. I dont think I can change this code.
        Cipher cipher = Cipher.getInstance(key.getAlgorithm() + "/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedData = cipher.doFinal(data);

        System.out.println("encryptedData: " + encryptedData.toString());

        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decryptedData = cipher.doFinal(data);

        System.out.println("decryptedData: " + decryptedData.toString());
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一梦等七年七年为一梦 2025-02-20 04:32:38

我唯一可以看到的问题是,您将未加密的数据传递给了“解密模式”的密码,而这将行不通。 (显然,密码无法解密未经奇怪结果而不会加密的数据。)
因此,更改

byte[] decryptedData = cipher.doFinal(data);

byte[] decryptedData = cipher.doFinal(encryptedData);

那时,一切正常。
Altough我怀疑您的生产代码中存在此错误,因此,如果您仍然有问题,请随时提出一个新问题。

The only issue I can see is that you pass the unencrypted data to the Cipher in decrypt mode, which won't work. (The cipher obviously cannot decrypt data which is not encrypted without getting odd results.)
So change

byte[] decryptedData = cipher.doFinal(data);

to

byte[] decryptedData = cipher.doFinal(encryptedData);

Then, everything works fine.
Altough I doubt this error exists in your productive code, so if you still have problems on that one, feel free to ask a new question.

清引 2025-02-20 04:32:38

您不是在解密加密数据,而只是试图解密原始数据。

同时打印数据时使用UTF-8

import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class PMAdminKeyTest {

    public static void main(String[] args) throws Exception {
        // Requirement is to generate Key based on password and salt
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec keySpec = new PBEKeySpec("password".toCharArray(), "salt".getBytes(), 65536, 192);
        SecretKey key = new SecretKeySpec(secretKeyFactory.generateSecret(keySpec).getEncoded(), "DESede");

        System.out.println("key.getAlgorithm(): " + key.getAlgorithm());

        byte[] data = "12345678".getBytes("UTF8");

        // Existing encrypt and decrypt code. There is already lot of data in DB
        // encrypted in this manner. I dont think I can change this code.
        Cipher cipher = Cipher.getInstance(key.getAlgorithm() + "/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedData = cipher.doFinal(data);

        System.out.println("encryptedData: " + encryptedData.toString());

        cipher.init(Cipher.DECRYPT_MODE, key);

        // Notice this
        byte[] decryptedData = cipher.doFinal(encryptedData);

        // while printing the data use UTF-8 
        System.out.println("decryptedData: " +  new String(decryptedData, "UTF-8"));
    }
}

You are not decrypting the encrypted data, you are simply trying to decrypt the original data.

Also while printing the data use UTF-8

import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class PMAdminKeyTest {

    public static void main(String[] args) throws Exception {
        // Requirement is to generate Key based on password and salt
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec keySpec = new PBEKeySpec("password".toCharArray(), "salt".getBytes(), 65536, 192);
        SecretKey key = new SecretKeySpec(secretKeyFactory.generateSecret(keySpec).getEncoded(), "DESede");

        System.out.println("key.getAlgorithm(): " + key.getAlgorithm());

        byte[] data = "12345678".getBytes("UTF8");

        // Existing encrypt and decrypt code. There is already lot of data in DB
        // encrypted in this manner. I dont think I can change this code.
        Cipher cipher = Cipher.getInstance(key.getAlgorithm() + "/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedData = cipher.doFinal(data);

        System.out.println("encryptedData: " + encryptedData.toString());

        cipher.init(Cipher.DECRYPT_MODE, key);

        // Notice this
        byte[] decryptedData = cipher.doFinal(encryptedData);

        // while printing the data use UTF-8 
        System.out.println("decryptedData: " +  new String(decryptedData, "UTF-8"));
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文