国密算法c#和Java互通

最近和外部系统对接,使用了国密算法,且我们这边是c#,对方是Java,折腾了一番后,把踩过的坑记录下来,有需要的可以参考。

一、密钥生成

我们这边生成密钥是用的bouncycastle.crypto库,一开始对方是用Java自带的加密库生成的密钥,结果是双方都使用不了对方的密钥,后来我们两边都统一使用bouncycastle.crypto库来生成密钥,问题解决。

二、密文格式

c#这边默认的密文格式是C1C2C3,而Java那边使用格式一开始是C1C3C2,导致加解密、加验签不成功,后来两边统一使用C1C2C3,问题解决。

总结:c#和Java国密互通,两边的密钥生成以及加解密、加验签都要统一使用bouncycastle.crypto库,密文格式也最好统一,如果不统一,需要C1C2C3和C1C2C3进行转换。

附加解密、加验签的代码

加密

cs 复制代码
public string EncryptM2(string message, string key)
        {
            X9ECParameters curve = ECNamedCurveTable.GetByName("sm2p256v1");
            ECPoint q = curve.Curve.DecodePoint(Base64.Decode(key));
            ECDomainParameters domain = new ECDomainParameters(curve);
            ECPublicKeyParameters pubk = new ECPublicKeyParameters("EC", q, domain);

            // 创建SM2加密器
            SM2Engine sm2Engine = new SM2Engine();
            sm2Engine.Init(true, new ParametersWithRandom(pubk, new SecureRandom()));

            byte[] dataBytes = Encoding.UTF8.GetBytes(message);
            byte[] encryptedData = sm2Engine.ProcessBlock(dataBytes, 0, dataBytes.Length);

            return Base64.ToBase64String(encryptedData);
        }

解密

cs 复制代码
public string DecryptM2(string message, string key)
        {
            X9ECParameters curve = ECNamedCurveTable.GetByName("sm2p256v1");
            ECDomainParameters domain = new ECDomainParameters(curve);
            BigInteger d = new BigInteger(1, Base64.Decode(key));
            ECPrivateKeyParameters prik = new ECPrivateKeyParameters(d, domain);

            // 创建SM2加密器
            SM2Engine sm2Engine = new SM2Engine();
            sm2Engine.Init(false, prik);

            byte[] encryptedData = Base64.Decode(message);
            byte[] decryptedData = sm2Engine.ProcessBlock(encryptedData, 0, encryptedData.Length);

            return Encoding.UTF8.GetString(decryptedData);
        }

加签

cs 复制代码
public string SignM2(string strPrivateKey, string strData)
        {
            byte[] messageBytes = System.Text.Encoding.UTF8.GetBytes(strData);

            X9ECParameters curve1 = ECNamedCurveTable.GetByName("sm2p256v1");
            ECDomainParameters domain1 = new ECDomainParameters(curve1);
            BigInteger d = new BigInteger(1, Base64.Decode(strPrivateKey));
            ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(d, domain1);

            ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
            signer.Init(true, new ParametersWithRandom(privKey, new SecureRandom()));
            signer.BlockUpdate(messageBytes, 0, messageBytes.Length);
            byte[] signature = signer.GenerateSignature();

            return Base64.ToBase64String(signature);
        }

验签

cs 复制代码
public bool verifySignM2(string strPublickey, string strData, string strSign)
        {
            byte[] messageBytes = System.Text.Encoding.UTF8.GetBytes(strData);
            byte[] signature = Base64.Decode(strSign);

            X9ECParameters curve = ECNamedCurveTable.GetByName("sm2p256v1");
            ECPoint q = curve.Curve.DecodePoint(Base64.Decode(strPublickey));
            ECDomainParameters domain = new ECDomainParameters(curve);
            ECPublicKeyParameters pubk = new ECPublicKeyParameters("EC", q, domain);

            ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
            signer.Init(false, pubk);
            signer.BlockUpdate(messageBytes, 0, messageBytes.Length);
            bool isVerified = signer.VerifySignature(signature);
            return isVerified;
        }
相关推荐
蛋蛋的就会顺顺的6 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
需要8267 小时前
Spring Bean 生命周期:从实例化到销毁的完整钩子
java·后端·spring
小 黄 鸡7 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
死磕音视频7 小时前
让小模型做选择题:限定候选项并读取 logits 概率的入门实践(附 Python 代码)
开发语言·python·大模型·文本分类·transformers
伯恩bourne9 小时前
Spring Boot Bean 注册的两种方式:@Component 家族 vs @Configuration + @Bean
java·spring boot·后端
silvamux_9 小时前
curl 测试 OpenAI 兼容 API 的完整流程
java·人工智能·缓存·ai·oneapi
省钱兄--zs10 小时前
深圳24小时自助健身房软硬件解决方案实战指南与开发流程详解
java·数据仓库·spring boot·小程序·架构
顽疲10 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
Wang's Blog10 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
用户212968352616810 小时前
开源了一个 Java 多智能体 LLM 框架 Baton:一个依赖,把 Agent 循环、工具调用、记忆、编排全配齐
java·llm