簡體   English   中英

努力存儲生成的鹽以進行AES加密/解密

[英]Struggling to store the generated salt for aes encryption/decryption

因此,我幾乎對加密一無所知-但我正在努力弄清楚。 我從這里獲得了一些示例代碼,但是當我重新啟動程序並重置INSTANCE時,我不知道如何調用解密方法。 我猜我需要某種方式來存儲鹽並將其解析為解密方法嗎? 任何幫助表示贊賞。

這是代碼:

public class AES {

    private static final String password = "encrypt";
    private static String salt;
    private static final int pswdIterations = 65536;
    private static final int keySize = 128;
    private byte[] ivBytes;

    public String encrypt(String plainText) throws Exception {

        //get salt
        salt = generateSalt();
        byte[] saltBytes = salt.getBytes("UTF-8");

        // Derive the key
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec spec = new PBEKeySpec(
                password.toCharArray(),
                saltBytes,
                pswdIterations,
                keySize
        );

        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

        //encrypt the message
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secret);
        AlgorithmParameters params = cipher.getParameters();
        ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
        byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
        return new Base64().encodeAsString(encryptedTextBytes);
    }

    @SuppressWarnings("static-access")
    public String decrypt(String encryptedText) throws Exception {

        byte[] saltBytes = salt.getBytes("UTF-8");
        byte[] encryptedTextBytes = new Base64().decodeBase64(encryptedText);

        // Derive the key
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec spec = new PBEKeySpec(
                password.toCharArray(),
                saltBytes,
                pswdIterations,
                keySize
        );

        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

        // Decrypt the message
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes));

        byte[] decryptedTextBytes = null;
        try {
            decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
        }

        return new String(decryptedTextBytes);
    }

    public String generateSalt() {
        SecureRandom random = new SecureRandom();
        byte bytes[] = new byte[20];
        random.nextBytes(bytes);
        String s = new String(bytes);
        return s;
    }
}

一種常見的方法是將生成的隨機鹽直接用作byte [], 並在將其編碼為base 64之前將其連接在密文前面。對於給定的代碼,這將是一個非常好的主意,如下所示:

String s = new String(bytes);

generateSalt方法中的錯誤,可能會丟失信息。 這將意味着生成了錯誤的密鑰,這意味着將丟失明文(除非通過強行強制加鹽來恢復)。 為了使事情變得有趣,這僅在鹽字節的特定值(即不規則的)上發生。

提示:不要依靠互聯網上的隨機代碼來學習加密。 您只會學到錯誤的操作方法(有超過100票的stackoverflow答案包含不安全的密碼!)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM