当前位置: 首页 > news >正文

哪个网站平面设计做的好石家庄学设计的正规学校

哪个网站平面设计做的好,石家庄学设计的正规学校,网站排名怎么做 site,上海网站邮箱制作Spring Boot中使用Bouncy Castle实现SM2国密算法#xff08;与前端JS加密交互#xff09;一、环境准备二、核心实现三、前后端交互流程四、关键问题解决方案五、常见问题排查六、最佳实践建议在现代Web应用中#xff0c;数据安全传输至关重要。SM2作为我国自主设计的非对称加… Spring Boot中使用Bouncy Castle实现SM2国密算法与前端JS加密交互一、环境准备二、核心实现三、前后端交互流程四、关键问题解决方案五、常见问题排查六、最佳实践建议在现代Web应用中数据安全传输至关重要。SM2作为我国自主设计的非对称加密算法在安全性、效率和合规性方面具有显著优势。本文将详细介绍如何在Spring Boot中集成SM2算法实现与前端JS的无缝加密交互。 一、环境准备 技术栈 Java 1.8Spring Boot 2.1.18Bouncy Castle 1.68前端sm-crypto或类似库 Maven核心依赖 dependenciesdependencygroupIdorg.bouncycastle/groupIdartifactIdbcprov-jdk15on/artifactIdversion1.68/version/dependency /dependencies二、核心实现 密钥生成服务 RestController RequestMapping(/sm2) public class SM2Controller {GetMapping(/keypair)public MapString, String generateKeyPair() throws Exception {KeyPair keyPair SM2CryptoUtil.generateKeyPair();ECPublicKey publicKey (ECPublicKey) keyPair.getPublic();ECPrivateKey privateKey (ECPrivateKey) keyPair.getPrivate();String publicKeyHex Hex.toHexString(publicKey.getQ().getEncoded(false));String privateKeyHex privateKey.getD().toString(16);// 标准化私钥格式64字符privateKeyHex String.format(%64s, privateKeyHex).replace( , 0);return Map.of(publicKey, publicKeyHex, // 130字符带04前缀privateKey, privateKeyHex // 64字符);} }SM2解密服务 import org.bouncycastle.asn1.gm.GMNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex;import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.util.Arrays;/*** author cmamg* title: Base64Util* projectName * description: TODO* date 2025/7/29*/ public class SM2CryptoUtil {// 加密模式常量public static final int C1C2C3 0;public static final int C1C3C2 1;// 椭圆曲线参数private static final X9ECParameters EC_PARAMS;private static final ECDomainParameters DOMAIN_PARAMS;private static final BigInteger CURVE_ORDER;static {Security.addProvider(new BouncyCastleProvider());EC_PARAMS GMNamedCurves.getByName(sm2p256v1);DOMAIN_PARAMS new ECDomainParameters(EC_PARAMS.getCurve(),EC_PARAMS.getG(),EC_PARAMS.getN(),EC_PARAMS.getH());CURVE_ORDER EC_PARAMS.getN();}/*** 生成SM2密钥对*/public static KeyPair generateKeyPair() throws Exception {ECNamedCurveParameterSpec spec ECNamedCurveTable.getParameterSpec(sm2p256v1);KeyPairGenerator kpg KeyPairGenerator.getInstance(EC, BC);kpg.initialize(spec, new SecureRandom());return kpg.generateKeyPair();}/*** 获取压缩公钥十六进制字符串*/public static String getCompressedPublicKey(ECPoint publicKey) {byte[] compressed publicKey.getEncoded(true);return Hex.toHexString(compressed);}/*** 获取未压缩公钥十六进制字符串不带04前缀*/public static String getUncompressedPublicKey(ECPoint publicKey) {byte[] uncompressed publicKey.getEncoded(false);// 去掉开头的04标识return Hex.toHexString(uncompressed);}/*** 从十六进制字符串解析公钥*/public static ECPoint parsePublicKey(String publicKeyHex) {// 添加04前缀表示未压缩格式byte[] pubKeyBytes Hex.decode( publicKeyHex);return DOMAIN_PARAMS.getCurve().decodePoint(pubKeyBytes);}private static BigInteger parsePrivateKey(String privateKeyHex) {if (privateKeyHex null || privateKeyHex.length() ! 64) {throw new IllegalArgumentException(私钥必须是64字符十六进制字符串);}try {BigInteger privateKey new BigInteger(privateKeyHex, 16);// 验证私钥范围 [1, n-1]if (privateKey.signum() 0 || privateKey.compareTo(CURVE_ORDER) 0) {throw new IllegalArgumentException(私钥超出有效范围);}return privateKey;} catch (NumberFormatException e) {throw new IllegalArgumentException(无效的私钥格式, e);}}public static String decryptStr(String ciphertextHex, String privateKeyHex) throws Exception {return new String(decrypt(ciphertextHex,privateKeyHex, 1), UTF-8);}/*** SM2解密*/public static byte[] decrypt(String ciphertextHex, String privateKeyHex, int cipherMode) throws Exception {// 1. 验证并解析私钥BigInteger privateKey parsePrivateKey(privateKeyHex);// 2. 解析密文byte[] ciphertext Hex.decode(ciphertextHex);// 验证最小长度 C1(64) C3(32) 96字节if (ciphertext.length 96) {throw new IllegalArgumentException(密文太短);}// 3. 拆分密文byte[] c1 Arrays.copyOfRange(ciphertext, 0, 64); // 64字节byte[] c3;byte[] c2;if (cipherMode C1C2C3) {// C1C2C3模式: C1(64) C2 C3(32)c3 Arrays.copyOfRange(ciphertext, ciphertext.length - 32, ciphertext.length);c2 Arrays.copyOfRange(ciphertext, 64, ciphertext.length - 32);} else {// C1C3C2模式: C1(64) C3(32) C2c3 Arrays.copyOfRange(ciphertext, 64, 96);c2 Arrays.copyOfRange(ciphertext, 96, ciphertext.length);}// 4. 重建C1点byte[] c1Full new byte[65]; // 04 64字节c1Full[0] 0x04; // 添加未压缩标识System.arraycopy(c1, 0, c1Full, 1, 64);ECPoint c1Point;try {c1Point DOMAIN_PARAMS.getCurve().decodePoint(c1Full);} catch (Exception e) {throw new IllegalArgumentException(无效的C1点, e);}// 5. 计算共享点 (x2, y2) privateKey * C1ECPoint s c1Point.multiply(privateKey).normalize();// 验证点是否在曲线上if (!s.isValid()) {throw new SecurityException(计算出的点不在曲线上);}byte[] x2 BigIntegers.asUnsignedByteArray(32, s.getXCoord().toBigInteger());byte[] y2 BigIntegers.asUnsignedByteArray(32, s.getYCoord().toBigInteger());// 6. KDF生成密钥流byte[] z new byte[x2.length y2.length];System.arraycopy(x2, 0, z, 0, x2.length);System.arraycopy(y2, 0, z, x2.length, y2.length);byte[] t kdf(z, c2.length);// 7. 异或解密byte[] msg new byte[c2.length];for (int i 0; i c2.length; i) {msg[i] (byte) (c2[i] ^ t[i]);}// 8. 验证C3byte[] u new byte[x2.length msg.length y2.length];System.arraycopy(x2, 0, u, 0, x2.length);System.arraycopy(msg, 0, u, x2.length, msg.length);System.arraycopy(y2, 0, u, x2.length msg.length, y2.length);byte[] calculatedC3 sm3(u);if (!Arrays.equals(c3, calculatedC3)) {throw new SecurityException(C3验证失败: 数据可能被篡改或密钥错误);}return msg;}/*** KDF密钥派生函数*/private static byte[] kdf(byte[] z, int keylen) {int ct 1;int offset 0;byte[] result new byte[keylen];SM3Digest digest new SM3Digest();while (offset keylen) {// 准备计数器字节byte[] ctBytes new byte[]{(byte) (ct 24),(byte) (ct 16),(byte) (ct 8),(byte) ct};// 计算SM3哈希digest.update(z, 0, z.length);digest.update(ctBytes, 0, 4);byte[] hash new byte[digest.getDigestSize()];digest.doFinal(hash, 0);// 填充结果int copyLen Math.min(keylen - offset, hash.length);System.arraycopy(hash, 0, result, offset, copyLen);offset copyLen;ct;digest.reset();}return result;}/*** SM3哈希计算*/private static byte[] sm3(byte[] input) {SM3Digest digest new SM3Digest();digest.update(input, 0, input.length);byte[] hash new byte[digest.getDigestSize()];digest.doFinal(hash, 0);return hash;} }前端加密示例 import { sm2 } from sm-crypto;// 使用后端生成的公钥130字符带04前缀 const publicKey 04d4de...; function encryptMessage(message) {// 使用C1C3C2模式加密const ciphertext sm2.doEncrypt(message, publicKey, 1 // cipherMode1 表示C1C3C2);return ciphertext; // 十六进制字符串 }// 调用示例 const encrypted encryptMessage(敏感数据123);三、前后端交互流程 密钥获取 GET /sm2/keypair Response: { publicKey: 04..., privateKey: a1b2... }前端加密 const ciphertext sm2.doEncrypt(data, publicKey, 1);后端解密 POST /sm2/decrypt {ciphertext: a1b2c3...,privateKey: a1b2...,mode: 1 }四、关键问题解决方案 公钥格式一致性 前端要求公钥带04前缀未压缩格式后端需确保 public String getPublicKeyHex(ECPoint publicKey) {return Hex.toHexString(publicKey.getEncoded(false)); // 带04前缀 }私钥范围验证 防止Scalar not in interval错误 private static final BigInteger CURVE_ORDER EC_PARAMS.getN();if (privateKey.signum() 0 || privateKey.compareTo(CURVE_ORDER) 0) {throw new IllegalArgumentException(无效私钥范围); }C1点重建 前端密文中的C1点不带04前缀后端需重建 byte[] c1Full new byte[65]; c1Full[0] 0x04; // 添加前缀 System.arraycopy(c1, 0, c1Full, 1, 64);五、常见问题排查 错误现象 可能原因 解决方案 Scalar not in interval 私钥格式错误或越界 验证私钥长度64字符值在[1, n-1]范围内 C3验证失败 密钥错误或数据篡改 检查公私钥配对重试加密流程 无效的C1点 密文格式错误 确认使用C1C3C2模式检查密文长度 解密乱码 编码不一致 统一使用UTF-8编码 六、最佳实践建议 密钥管理 前端不存储私钥 后端使用HSM或KMS管理私钥 定期轮换密钥 性能优化 // 重用SM3Digest实例 private static final ThreadLocalSM3Digest sm3Cache ThreadLocal.withInitial(SM3Digest::new);安全增强 // 防止时序攻击 if (!MessageDigest.isEqual(c3, calculatedC3)) {throw new SecurityException(C3验证失败); }七、总结 本文实现了Spring Boot中完整的SM2算法集成方案重点解决了 密钥生成与格式标准化 与前端JS的加密交互 解密过程中的异常处理 通过此方案开发者可以快速构建符合国密标准的安全应用确保数据传输的机密性和完整性。在实际业务中建议结合HTTPS等传输层安全措施构建纵深防御体系。
http://www.zqtcl.cn/news/131767/

相关文章:

  • 换物网站为什么做不起来网站开发工具的功能包括
  • 引导式网站君和网站建设
  • 西柏坡门户网站建设规划书自己做照片书的网站
  • 做网站横幅的图片多大公司做自己的网站平台台
  • 百度网站建设工资给城市建设提议献策的网站
  • 如何进入网站管理页面维护网站需要多少钱
  • 深圳住房和城乡建设局网站阿里云学生免费服务器
  • 如何做的网站手机可以用吗绵阳优化网站排名
  • 营销网站建设大全wordpress wp_register
  • 公司做年审在哪个网站网络seo专员招聘
  • 宿州网站建设费用网站快速建设入门教程
  • 怎么自己做网站加盟网站建设意义模板
  • 网站开发怎样实现上传视频教程内容导购网站模板
  • 济南做网站建设的公司广告公司资质
  • 域名分类网站微擎 wordpress
  • 公司产品营销策划安徽seo
  • 网站 平均加载时间百度搜索竞价推广
  • 赛车网站开发淄博网站建设及托管
  • 过时的网站湖州公司网站建设
  • 环球设计网站网站建设的面试要求
  • 百度公司网站排名怎么做潮阳网站开发
  • 杨和网站建设国内外建筑设计网站
  • 北京知名网站建设公司wordpress4.0.x 下载
  • 锡盟网站建设做网站视频存储
  • 深圳博纳网站建设高端品牌护肤品排行榜
  • 百度爱采购优化排名软件宁波seo搜索平台推广专业
  • 门户网站的建设公司台山网站定制
  • 建设公司网站需要什么群辉nas怎么做网站
  • 广西自治区集约化网站建设要求坂田网站的建设
  • 网站后台不能编辑企业如何申请网站