当前位置: 首页 > 知识库问答 >
问题:

PBEWithHmacSHA512AndAES_128和AES模式,如GCM

解晟睿
2023-03-14

首先,我已经成功地使用Java(JDK 8)编写了使用pbewithhmacsha512andaes128进行加密和解密的代码。

但我想知道这是否是AES,那么如何使用GCM这样的模式来检查完整性。

另一方面,我能够将AES/GCM/NoPaddingPBKDF2WithHmacSHA256结合使用。表示密钥是使用带有HMACSHA256的PBKDF2生成的,用于AES/GCM。

>

  • 但我正在努力寻找使用PBEWithHmacSHA512AndAES_128生成密钥的源代码,并使用AES/GCM,或者即使这是可能的,或者它是否有意义?

    其次,使用PBEWithHmacSHA512AndAES_128生成的密钥始终是9字节——如果是这样,那么我想知道AES 128需要大小为16字节的密钥,以及密钥是如何生成为9字节的?

    非常感谢您在这方面的任何帮助/澄清。。。

    使用PBEWithHmacSHA512AndAES_128编码

    private byte[] getRandomNumber(final int size) throws NoSuchAlgorithmException {
        SecureRandom secureRandom = SecureRandom.getInstanceStrong();
        byte[] randomBytes = new byte[size];
        secureRandom.nextBytes(randomBytes);
        return randomBytes;
    }
    
    
    private SecretKey getPBE_AES_Key(final String password, final byte[] salt) {
        try {
            char[] passwdData = password.toCharArray();
    
            PBEKeySpec pbeKeySpec = new PBEKeySpec(passwdData, salt, 4096, 128);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_128");
            SecretKey pbeKey = keyFactory.generateSecret(pbeKeySpec);
            return pbeKey; // <-- size of this byte array is 9 - I thought it should be 16 since its AES 
        } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
            throw new OperationFailedException(ex.getMessage(), ex);
        }
    }
    
    
    public String encrypt_PBE_AES(final String plaintext, final String password) {
        try {
            byte[] ivBytes = getRandomNumber(16);
            byte[] saltBytes = getRandomNumber(16);
            byte[] dataToEncrypt = plaintext.getBytes("UTF-8");
    
            Cipher cipher = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
            PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(saltBytes, 4096, ivParameterSpec);
    
            cipher.init(Cipher.ENCRYPT_MODE, getPBE_AES_Key(password, saltBytes), pbeParameterSpec);
            byte[] encryptedData = cipher.doFinal(dataToEncrypt);
    
            byte[] ivWithSalt = ArrayUtils.addAll(ivBytes, saltBytes);
            byte[] encryptedDataWithIVAndSalt = ArrayUtils.addAll(ivWithSalt, encryptedData);
            String encodedData = Base64.getUrlEncoder().encodeToString(encryptedDataWithIVAndSalt);
            return encodedData;
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException
            | BadPaddingException | IOException | InvalidAlgorithmParameterException ex) {
            throw new OperationFailedException(ex.getMessage(), ex);
        }
    }
    
    public String decrypt_PBE_AES(final String ciphertext, final String password) {
        try {
            byte[] encryptedDataWithIVAndSalt = Base64.getUrlDecoder().decode(ciphertext);
            byte[] ivBytes = ArrayUtils.subarray(encryptedDataWithIVAndSalt, 0, 16);
            byte[] saltBytes = ArrayUtils.subarray(encryptedDataWithIVAndSalt, 16,
                16 + 16);
            byte[] dataToDecrypt = ArrayUtils.subarray(encryptedDataWithIVAndSalt,
                16 + 16, encryptedDataWithIVAndSalt.length);
    
            Cipher cipher = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
            PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(saltBytes, 4096, ivParameterSpec);
    
            cipher.init(Cipher.DECRYPT_MODE, getPBE_AES_Key(password, saltBytes), pbeParameterSpec);
            byte[] decryptedData = cipher.doFinal(dataToDecrypt);
    
            return new String(decryptedData, "UTF-8");
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | UnsupportedEncodingException
            | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException ex) {
            throw new OperationFailedException(ex.getMessage(), ex);
        }
    }
    

    如你所见,有两个问题。。。

    在我的代码中,我用密文保存静脉注射和盐。我想使用AES/GCM来检查整个静脉注射盐的完整性。

    b)为什么密钥的字节[]是9字节?(当我输入为Pree@2017时,生成的密钥是9字节-我检查了pbeKey.getEncoded()的长度及其9。

    很多谢谢

    更新-第一个问题的答案如下。然而,第二个问题最终得到了回答https://crypto.stackexchange.com/questions/46849/pbewithhmacsha512andaes-128-and-aes-modes-like-gcm

    谢谢大家!


  • 共有1个答案

    家志学
    2023-03-14

    另一方面,我能够将AES/GCM/NoPaddingPBKDF2WithHmacSHA256结合使用。

    完美。您似乎想要默认为AES-128。如果实现正确,上面的错误很小,换成SHA-512在安全方面不会有太大帮助(如果有的话)。

    但我正在努力寻找使用PBEWithHmacSHA512AndAES_128和使用AES/GCM生成密钥的来源,或者即使这是可能的,或者如果它有意义?

    AES_128已经表明该html" target="_blank">模式不使用完整性。这是一种全有或全无的方案,默认为CBC。如上所述,我只保留你所拥有的。

    其次,使用pbewithhmacsha512andaes128生成的密钥始终是9字节——如果是这样,那么我想知道AES 128需要大小为16字节的密钥,以及密钥是如何生成为9字节的?

    这不可能是对的。毫无疑问,密钥是128位/16字节,但您只是得到了错误的信息,例如,试图直接打印底层字节数组,而不是首先将其转换为十六进制。

     类似资料:
    • 我有一个128,192和256位密钥的AES密码的实现。我正在尝试实现分组密码模式的操作,目前正在实现密码分组链接模式。 关于CBC模式的实施,我有两个问题: 1.这是关于向密码例程提供数据的,我在<code>cbc()中调用密码例程\\此函数实现cbc模式</code>。我的问题是,我应该读取<code>cbc()</code>中的文件(包含用于加密的数据),还是可以读取<code>cbc(()

    • 编辑:问题可以简化为:下面的Node.js代码给出了一个“无效的IV长度”错误。为什么?静脉注射应该是什么? 我在GCM模式下使用AES来加密一些数据,但我使用两种不同的语言和库来加密和解密,它们似乎对我需要的东西有不同的词汇表。 我正在使用Python库(Crypto)进行加密。方法接受128位密钥和消息,并返回128位nonce、128位标记和密文。 (加密代码取自本例) 我用默认的node.

    • 我有下面的代码,使用我在这里找到的一个简单的面向字节的AES-256库为AES-256 ECB加密工作。 主要: 加密功能: 我想在此程序中添加一个IV以创建AES-256 CBC模式。根据我的理解,IV实现如下: 将第一个块与IV进行异或。 将所有后续块与前一块的密码文本进行异或 我的问题是逻辑是什么样的?我如何将其实现到我的代码中?

    • 我之所以问这个问题,是因为两天来我读了很多关于crypto AES加密的帖子,就在我以为我得到了它的时候,我意识到我根本没有得到它。 这个帖子是最接近我的问题,我有完全相同的问题,但它没有得到回答: CryptoJS AES加密与JAVA AES解密值不匹配 我得到的是已经加密的字符串(我得到的代码只是为了看看他们是怎么做的),所以修改加密方式不是一个选项。这就是为什么所有类似的问题对我来说都不是