使用 Java 的 AES-256-GCM 解密中的标签不匹配错误

2023-11-29

我用 Javascript 编写了以下函数,用于使用 aes-256-gcm 进行加密:

encrypt: function (text, masterkey){
    try {
        // random initialization vector
        var iv = crypto.randomBytes(12);

        // random salt
        var salt = crypto.randomBytes(64);

        // derive key: 32 byte key length - in assumption the masterkey is a cryptographic and NOT a password there is no need for
        // a large number of iterations. It may can replaced by HKDF
        var key = crypto.pbkdf2Sync(masterkey, salt, 2145, 32, 'sha512');

        // AES 256 GCM Mode
        var cipher = crypto.createCipheriv('aes-256-gcm', key, iv);

        // encrypt the given text
        var encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]);

        // extract the auth tag
        var tag = cipher.getAuthTag();

        // generate output
        return Buffer.concat([salt, iv, tag, encrypted]).toString('base64');

    }catch(e){
    }

    // error
    return null;
}

使用以下函数成功解密上述函数的加密文本:

decrypt: function (data, masterkey){
    try {
        // base64 decoding
        var bData = new Buffer(data, 'base64');
        var salt = bData.slice(0, 64);
        var iv = bData.slice(64, 76);
        var tag = bData.slice(76, 92);
        var text = bData.slice(92);

        // derive key using; 32 byte key length
        var key = crypto.pbkdf2Sync(masterkey, salt , 2145, 32, 'sha512');
        // AES 256 GCM Mode
        var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
        decipher.setAuthTag(tag);

        // decrypt the given text
        var decrypted = decipher.update(text, 'binary', 'utf8') + decipher.final('utf8');

        return decrypted;

    }catch(e){
    }

    // error
    return null;
}

现在,我需要 Java 中的解密方法,该方法相当于上面的 Javascript 解密函数。以下是我编写的用于解密的Java代码:

public void decrypt(byte[] nkb, String crKey){
    //nkb is byte array formed by Base64 decoding of 'data' variable in the Javascript code
    //crKey corresponds to the 'masterkey' variable

    byte[] salt = Arrays.copyOfRange(nkb, 0, 64);
    byte[] iv = Arrays.copyOfRange(nkb, 64, 76);
    byte[] tag = Arrays.copyOfRange(nkb, 76, 92);
    byte[] text = Arrays.copyOfRange(nkb, 92, nkb.length);

    PBEKeySpec ks = new PBEKeySpec(crKey.toCharArray(), salt, iterations, 256);
    SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
    SecretKey pbeKey = skf.generateSecret(ks);

    byte[] decrypted = decrypt(iv, pbeKey.getEncoded(), text, tag);
}
    public static byte[] decrypt(byte[] ivBytes, byte[] keyBytes, byte[] textBytes, byte[] tagBytes)
        throws java.io.UnsupportedEncodingException,
        NoSuchAlgorithmException,
        NoSuchPaddingException,
        InvalidKeyException,
        InvalidAlgorithmParameterException,
        IllegalBlockSizeException,
        BadPaddingException,
        NoSuchProviderException {

        GCMParameterSpec ivSpec = new GCMParameterSpec(tagBytes.length*Byte.SIZE, ivBytes);

        SecretKeySpec newKey = new SecretKeySpec(keyBytes, "AES");

        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
        return cipher.doFinal(textBytes); //getting tag mismatch error here
    }

正如我在上面的代码中评论的那样,我在最后一行收到标签不匹配错误。我希望能得到一些帮助来找出我做错了什么。

我在这行代码中有错误:

cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec)
java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)
at javax.crypto.Cipher.implInit(Cipher.java:805)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1396)
at javax.crypto.Cipher.init(Cipher.java:1327)
at com.micropro.namwebservice.utils.CryptoUtils.decrypt(CryptoUtils.java:93)
at com.micropro.namwebservice.utils.CryptoUtils.decrypt(CryptoUtils.java:82)

您需要向 Java GCM 代码提供标签,以便它可以检查消息是否真实。 Java API 期望将标签附加到密文中。更改代码的最简单方法是替换该行

return cipher.doFinal(textBytes);

有两行:

cipher.update(textBytes);
return cipher.doFinal(tagBytes);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Java 的 AES-256-GCM 解密中的标签不匹配错误 的相关文章

随机推荐

  • 一次对 n 行分组数据框应用自定义函数

    用户定义的函数 CollageImage lt function path country strain assay subgroup img out lt magick image read path gt magick image tr
  • HangFire 重复任务数据

    我正在编写 MVC 5 互联网应用程序并正在使用HangFire用于重复性任务 如果我有每月重复任务 如何获取下一次执行时间的值 这是我的重复任务的代码 RecurringJob AddOrUpdate AccountMonthlyActi
  • 为什么我的输出没有被赋值?

    我正在为一个更大项目的一部分开发解码器 我有两个计数器充当该模块的输入 其中一个计数器计数 0 15 另一个计数器在第一个计数器达到 15 时递增一次 根据计数器的值 解码器输出不同的值 通常它是 0 1 或 1 但有时它必须是 0 707
  • 如何将 BufferedImage 转换为某种颜色?

    具体来说 我的图像都是透明的纯黑色 我想在绘制图像时为图像分配任意颜色 以便黑色区域更改为新颜色 我尝试使用 RGBImageFilter 它只返回我想要的颜色 但出了问题并且根本没有绘制任何内容 ColourFilter 扩展了 RGBI
  • TableView 中具有多个部分的正确 indexPath.row 选择?

    我有多个部分的表视图 每个部分都有不同的行数 当我选择特定部分中的特定行时 如何找到正确的indexPath row 有教程吗 我不知道你所说的 正确 是什么意思 这indexPath row始终是该部分的本地变量 这意味着 section
  • 在 AJAX 加载的页面中使用 fancybox

    我在这个组中搜索并四处搜索 但仍然没有找到答案 我还看到有些人有我的问题 但线程没有帮助 所以我在这里 这个问题很简单 为了帮助你 我打包了一个 zip 其中包含 您可以测试的文件 http www ivanhalen com fancyp
  • 使用 Linq to Entities 插入现有行的副本 [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我正在使用实体框架 我有一个带有自动生成的主键的表以及与其他主数据表的许多外键关系 我们需要一个复制功能 其中我们可以从表中选择任何现有行并将其作为副本插入到同一个表中 我需要复制所
  • 来自 Makefile 子目录的源代码

    我有一个使用 Makefile 构建的 C 库 直到最近 所有源代码都在一个目录中 并且 Makefile 做了类似的事情 SOURCES wildcard cpp 效果很好 现在我添加了一些位于子目录中的源 例如subdir 我知道我能做
  • 使用 dplyr 更改第一行 group_by 主题 ID 的变量值

    超过 2 000 个科目 我想按主题将每个第一行的 time2 值更改为 0 例如 ID 2 主题的第一行的 time2 为 1 考虑到 2k 科目 如何将其更改为 0 ID time1 time2 1 0 0 1 0 1 1 1 5 2
  • 如何通过单击取消选中单选按钮?

    与复选框不同 单选按钮一旦被单击 用户就无法取消选择 有什么方法可以使用 Javascript 以编程方式切换它们吗 最好不使用 jQuery 您可以设置 HTML 对象的属性checked to false像这样 document get
  • 如何在构建时始终运行命令而不考虑任何依赖项?

    我想运行一个解析整个源代码树的 cmake 命令 因此我无法列出 cmake 的 add custom command add custom target 命令中所有可能的依赖项 是否可以告诉 cmake 不带任何条件地运行命令 我尝试了在
  • 运动事件问题

    我想知道如何获得 MotionEvent 的准确 get x 和 get y 值 发生的情况是 当我触摸屏幕上的特定区域时 我会告诉要发生一个动作 问题是 一旦我触摸屏幕并将手指移开 它仍然认为我的手指位于同一位置 因为这是我最后触摸的位置
  • 如何在网格布局中显示二维数组

    I have Array myArray new Array 5 5 or Array myArray new Array 7 9 or new Array 12 13 我想将数组显示在GridLayout 我找到了很多例子 但没有二维数组
  • 适用于 MVC 5 模型的 Typeahead.js

    我刚刚使用 MVC 5 模型包装器的 Typeahead js 实现了 typeahead 功能 http timdwilson github io typeahead mvc model 一切正常 但我只是不知道如何设置建议下拉列表中显示
  • 处理 Chrome 中的“Enter”/“Return”键

    我有一个 AJAX y 类型的页面 当用户单击 GO 时 我需要执行特定的 JavaScript 函数 我还想在用户点击 Enter 或 Return 时模拟 GO 点击 请注意 我不想 提交 页面 原因是因为我是通过 JavaScript
  • 如何更改 Nimbus 中单个 JProgressBar 的颜色?

    我正在尝试更改 Nimbus LAF 外观和感觉 中单个 JProgressBar 的颜色 这个解决方案确实有效 但它改变了所有 JProgressBars 的颜色 UIDefaults defaults UIManager getLook
  • 更改窗口内容时的资源管理

    首先 我觉得自己并没有完全了解如何在窗口的多个 页面 之间导航 例如 我有一个名为 MainWindow 的窗口 在其中 我有一个页眉和一个页脚 中间是一个包含内容的面板 该面板最初包含内容 A 单击 A 中的某些内容后 我想从视图中删除
  • 具有扩展接口的派生类的集合。如何在没有动态转换的情况下访问派生接口?

    假设我有一个 动物 类型的抽象对象 动物有公纯虚法 吃 我想将 Animal 派生为 狗 和 猫 每个都有一个扩展接口 例如 我希望 Dog 有一个公共方法 chases Tail 而 Cat 有一个公共方法 destroy Furnitu
  • 如何启用嵌入式 tomcat 日志记录

    我在我的java应用程序中使用嵌入式tomcat 下面是我的源代码 但是 tomcat 没有生成任何日志 embedded new Embedded embedded setDebug 3 org apache catalina logge
  • 使用 Java 的 AES-256-GCM 解密中的标签不匹配错误

    我用 Javascript 编写了以下函数 用于使用 aes 256 gcm 进行加密 encrypt function text masterkey try random initialization vector var iv cryp