无法使用 Java 解密 AES-256 GCM

2023-12-30

我有一个节点模块,可以使用 AES-256 GCM 进行加密和解密。现在我还尝试用 Java 解密节点模块加密的任何内容,但我不断收到 AEADBadTagException。

我已经自行测试了节点模块,并可以确认它按预期工作。我知道 Java 假定身份验证标签是消息的最后一部分,因此我确保该标签是添加到节点模块中的最后一个部分。

现在我只是用“hello”这个词进行测试。这是来自节点的加密消息:Q10blKuyyYozaRf0RVYW7bave8mT5wrJzSdURQQa3lEqEQtgYM3ss825YpCQ70A7hpq5ECPafAxdLMSIBZCxzGbv/Cj4i6W4JCJXuS107rUy0tAAQVQQA2ZhbrQ0gNV9QA==

现在并没有真正使用盐,因为我试图让事情变得简单以用于测试目的

节点模块:

var crypto = require('crypto');

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

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

    var key = masterkey;

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

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

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

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

var decrypt = function(masterkey, encryptedText) {
    // base64 decoding
    var bData = new Buffer(encryptedText, 'base64');

    // convert data to buffers
    var salt = bData.slice(0, 64);
    var iv = bData.slice(64, 76);
    var tag = bData.slice(bData.length - 16, bData.length);
    var text = bData.slice(76, bData.length - 16);

    var key = masterkey;

    // AES 256 GCM Mode
    var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
    decipher.setAuthTag(tag);

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

    return decrypted;
};

module.exports = {
    encrypt: encrypt,
    decrypt: decrypt
}

Java类: main 方法目前仅用于测试,稍后将被删除。

package decryption;

import java.util.Arrays;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class DecryptAES256 {

    private static String salt;
    private static byte[] ivBase64;
    private static String base64EncryptedText;
    private static String key;

    public static void main(String[] args) {
        String key = "123456789aabbccddeefffffffffffff";
        String sourceText = "Q10blKuyyYozaRf0RVYW7bave8mT5wrJzSdURQQa3lEqEQtgYM3ss825YpCQ70A7hpq5ECPafAxdLMSIBZCxzGbv/Cj4i6W4JCJXuS107rUy0tAAQVQQA2ZhbrQ0gNV9QA==";
        System.out.println(decrypt(key, sourceText));
    }

    public static String decrypt(String masterkey, String encryptedText) {
        byte[] parts = encryptedText.getBytes();
        salt = new String(Arrays.copyOfRange(parts, 0, 64));
        ivBase64 = Arrays.copyOfRange(parts, 64, 76);
        ivBase64 = Base64.getDecoder().decode(ivBase64);
        base64EncryptedText = new String(Arrays.copyOfRange(parts, 76, parts.length));
        key = masterkey;
        byte[] decipheredText = decodeAES_256_CBC();
        return new String(decipheredText);
    }

    private static byte[] decodeAES_256_CBC() {
        try {
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            byte[] text = base64EncryptedText.getBytes();
            GCMParameterSpec params = new GCMParameterSpec(128, ivBase64, 0, ivBase64.length);
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, params);
            return cipher.doFinal(Base64.getDecoder().decode(text));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Failed to decrypt");
        }
    }
}

抛出异常是正常的,你的Java代码中有两个问题:

1- 您的 AES 密钥未正确解码:它被包裹在十六进制表示中,并且您将其解码,就好像它不是一样。调用时需要将其从十六进制表示形式转换为字节SecretKeySpec().

替换以下行:

SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

通过这个:

SecretKeySpec skeySpec = new SecretKeySpec(Hex.decodeHex(key.toCharArray()), "AES");

请注意,要访问 Hex 类,您需要导入org.apache.commons.codec.binary.Hex在您的类文件中并包含相应的 Apache公共编解码器您项目中的库。

2- 您在将 Base64 密文转换为 Base64 之前对其进行了拆分,这不是正确的做事顺序:

在你的开始时decrypt()方法,你需要first call Base64.getDecoder().decode()在你的密文上(sourceText),然后将其拆分为相应的字段。

如果您想要在 Java 中使用 AES-256-GCM 的示例,您可以查看我几个月前编写的以下示例:https://github.com/AlexandreFenyo/kif-idp-client https://github.com/AlexandreFenyo/kif-idp-client

加密和解密的源代码在以下文件中:https://github.com/AlexandreFenyo/kif-idp-client/blob/master/src/kif/libfc/Tools.java https://github.com/AlexandreFenyo/kif-idp-client/blob/master/src/kif/libfc/Tools.java

查看名为的方法encodeGCM() and decodeGCM().

这些方法由此处的主类调用:https://github.com/AlexandreFenyo/kif-idp-client/blob/master/src/kif/libfc/CommandLine.java https://github.com/AlexandreFenyo/kif-idp-client/blob/master/src/kif/libfc/CommandLine.java

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

无法使用 Java 解密 AES-256 GCM 的相关文章

  • 静态方法的 Java 内存模型

    我来自操作系统和 C 语言背景 在代码编译时 世界很简单 需要处理和理解堆栈 堆文本部分等 当我开始学习 Java 时 我确实了解 JVM 和垃圾收集器 我对静态方法感到很有趣 根据我的理解 类的所有实例都会在堆中创建 然后被清理 但是 对
  • Passport-local-mongoose:createStrategy 不是函数/authenticate 不是函数

    我正在构建这个启动项目 https github com cj wang mean start tree 424e6056e33bb16874ae808daf3780d53309296f并尝试添加用户登录护照本地猫鼬 https www n
  • RSA SignatureException:签名长度不正确

    我在签署 rsa 签名时遇到问题 我有一个用私钥加密的签名 然而 当我尝试使用公钥验证它时遇到问题 我得到以下异常 java security SignatureException Signature length not correct
  • 获取请求的客户端 IP 地址而不是 Cloudflare 的 IP 地址

    Cloudflare 会更改传入请求的 IP 地址 因为 Cloudflare 是我的网站和互联网之间的中间件 代理 我该怎么办获取请求的初始IP地址 而不是 Cloudflare 的 IP 地址 我听说过mod cloudflare但是这
  • Java 唤醒休眠线程

    我阅读了其他帖子 但没有找到我正在寻找的确切答案 所以我希望有人能给出一些澄清 我有一个将运行一段时间的程序 我有一些在后台运行的线程来执行各种任务 为了简单起见 让我们考虑 3 个线程 ThreadA每 10 秒执行一次任务 其中Thre
  • Java 泛型:如何为泛型类型指定类类型?

    我有一个 POJO 指定为 MyClass u where U是泛型类型参数 我正在尝试编写一个接受类引用的实用方法Class u
  • 从 sbt 程序集运行 uber jar 会导致错误:无法找到或加载主类

    我有一个使用 sbt 程序集插件打包为 uber jar 的 Spark 作业 这build sbt指定一个可运行的 main 作为生成的 uber jar 的目标 mainClass in assembly Some com foo Ba
  • 使用 OpenSSL 在 PHP 中进行 AES 加密/在 Node.js 中进行解密

    我正在使用 PHP 和 Nodejs 使用 OpenSSL 进行对称加密 PHP 使用 OpenSSL 库 Node js 解密基于实现的加密 问题是 Node js 中的解密文本只是部分正确 PHP 加密函数 function encry
  • Java元数据读写

    是否可以以通用方式 对于所有图像类型 在 Java 中读取和写入元数据 我找到了一些示例 但它们总是特定的 例如 JPEG 或 PNG 我需要一些足够通用的东西 而不是到处都有 if else 语句 我不想重写源代码 但这是一个很好的例子
  • 使用Java开发跨平台,不同平台字体缩放不同

    我正在为我的大学制作一些软件 需要一个 GUI 在它的第一个版本中 我让它使用系统外观 因此它看起来像 Linux Mac Windows 中的本机应用程序 我发现这很麻烦 因为我必须根据操作系统使所有 JLabel 具有不同的大小 无论分
  • 在 GraphQL 服务器中实现访问控制的好模式是什么?

    背景 我有一组模型 包括用户和各种其他模型 其中一些模型包含对用户的引用 我公开这些模型 以便通过 GraphQL API 生成的查询Graffiti https github com RisingStack graffiti 由 Mong
  • 是否可以为 azure blob 存储中的给定目录生成具有写入权限的 SAS(共享访问签名)

    我们的 blob 存储帐户结构 容器名称 simple 在这个容器内我们有 blob aa one zip aa two zip bb ss zip bb dd zip 是否可以生成对aa 目录 有写权限 但对bb 目录 没有访问权限的SA
  • 如何使用云打印打印Android活动显示

    我正在尝试将 Google 云打印实现到应用程序中 遵循集成指南 https developers google com cloud print docs android 我试图通过打印 google com 来保持基本 单击我创建的打印按
  • 找不到符号assertEquals

    我正在尝试为计算器编写第一个单元测试 但 NetBeans 说它找不到该符号assertEquals和注释 Test 我应该包括一些东西吗 我正在使用 NetBeans 7 3 1 和 W7 package calculator impor
  • H2 - (相当)长的 INSERT 失败,错误 42000

    H2 内存中 插入 错误 42000 尝试过版本 1 4 196 1 4 197 1 4 199 我还尝试在 H2 服务器 本地 上执行 INSERT 也失败 给出错误的行 抱歉 但出于安全原因 我无法生成更多 INSERT INTO tb
  • 将带有 webapp 的 WAR 部署到 Maven 中央存储库是否有意义?

    这样做有意义吗 如果是 我在哪里可以找到使用简单的 Web Hello World 执行此操作的示例 当人们从 Maven 执行 Web 应用程序时 他们会使用 Jetty 来运行它吗 我想 tomcat 太重了 任何帮助将不胜感激 谢谢
  • 如何从spark中的hbase表中获取所有数据

    我在 hbase 中有一个大表 名称为 UserAction 它具有三个列族 歌曲 专辑 歌手 我需要从 歌曲 列族中获取所有数据作为 JavaRDD 对象 我尝试了这段代码 但效率不高 有更好的解决方案来做到这一点吗 static Spa
  • 编写自定义 Eclipse 调试器

    EDIT 一定有某种方法可以解决这个问题 而无需编写全新的调试器 我目前正在研究在现有 java 调试器之上构建的方法 如果有人对如何获取 Java 调试器已有的信息 有关堆栈帧 变量 原始数据等 有任何想法 那将非常有帮助 我想要做的是我
  • H2 用户定义的聚合函数 ListAgg 不能在第一个参数上使用 DISTINCT 或 TRIM()

    所以我有一个 DB2 生产数据库 我需要在其中使用可用的函数 ListAgg 我希望使用 H2 的单元测试能够正确测试此功能 不幸的是H2不直接支持ListAgg 但是 我可以创建一个用户定义的聚合函数 import java sql Co
  • 尝试在节点 0.12 上重新安装 `node-sass`?

    我想使用谷歌网络入门套件 我安装了node js v0 12 0 node sass gulp 然后跑 sudo npm install 当我打字时gulp serve然后得到这个错误 Using gulpfile web starter

随机推荐