SM2公钥加密

2023-11-15

简介

国密SM2算法并不仅仅是提供了新的曲线参数,而是在算法上对ECC进行了修改。

SM2的曲线使用了Weierstrass模型:
y 2 = x 3 + a x + b m o d    P y^2=x^3+ax+b \mod P y2=x3+ax+bmodP

推荐参数

p=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF
a=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC
b=28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93
n=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123
Gx=32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7
Gy=BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0

1. 前置条件

1.1 点到字符串的转换

椭圆曲线是关于x轴对称的,点和字节数据转换时,y坐标只需要获取/提供正负即可。

压缩

PC(Padding Char) = 02或03;

int nLsbY = epoint_get(epointC1, bigX, bigX);
if (0 == nLsbY)
{
    PC = 2;
}
else // 1 == nLsbY
{
    PC = 3;
}
S = PC || bigX;

未压缩

PC = 04

PC = 04;
S = PC || X1 || Y1;

混合形式

PC = 06或07

int nLsbY = epoint_get(epointC1, bigX, bigY);
if (0 == nLsbY)
{
    PC = 6;
}
else // 1 == nLsbY
{
    PC = 7;
}
S = PC || bigX || bigY;

1.2 密钥派生函数

 int KDF(const uint8_t* pData
	, uint32_t nData
	, uint32_t nKeyBytesLen
	, PFnHash pfnHash
	, uint32_t nHash
	, uint8_t* pOut	)
{
	int nRet = 0;
	uint32_t nLoop = 0;
	uint32_t zt = 1;
	uint32_t i = 0;

	uint8_t *pBuf = NULL;
	uint32_t nBuf = nData + 4/*sizeof(zt)*/;
	if (!pData || !pOut)
	{
		return 0;
	}


	// alloc memory
	pBuf = (uint8_t *)calloc(nBuf, 1);
	if(!pBuf) return 0;
	memcpy(pBuf, pData, nData);

	nLoop = (nKeyBytesLen + nHash - 1) / nHash;	// upper(nKeyBytesLen/nHash)
	for (i = 0; i < nLoop; ++i)
	{
		u32to8_big(&(pBuf[nData]), zt);
		if (ERR_OK != pfnHash(pBuf, nBuf
			, pOut + i * nHash, nHash))
		{
			break;
		}
		++zt;
	}
	if (i == nLoop)
	{
		nRet = nKeyBytesLen;
	}
	return nRet;
}

6. 加解密

加密流程

  1. 生成随机数k
  2. 计算点C1 = kG = (Xc1, Yc1)
  3. 大数库可能封装了这一步:公钥为Q, h为余因子,S=[h]Q ,若S是无穷远点,则报错并退出;
  4. kQ = (x2, y2)
  5. t=KDF(x2 ∥ y2, nMsg), 若t为全0比特串,则报错并退出
  6. C2 = Msg xor t
  7. C3 = Hash(x2 || Msg || y2)
  8. Cipher = C1 || C2 || C3,C1压缩方式任意。

官网加解密示例使用了未压缩的转换方式。

解密流程

  1. 从密文中取出C1,验证是否为曲线上的点;
  2. 点S=[h]C1,若S是无穷远点,则报错并退出;
  3. 私钥为d,dC1 = (x2, y2)
  4. t=KDF(x2 ∥ y2, nMsg),这一步nMsg = nCipher - nC1 - nHash
  5. 取出C2, Msg = C2 xor t
  6. 验证u = Hash(x2 ∥ Msg ∥ y2) == C3,
  7. 明文为Msg

实现

https://github.com/C0deStarr/CryptoImp/tree/main/pubkey/ecc

  • sm2.h
  • sm2.c

参考资料

国家密码管理局关于发布《SM2椭圆曲线公钥密码算法》公告(国密局公告第21号)_国家密码管理局 (sca.gov.cn)

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

SM2公钥加密 的相关文章

  • Java如何使用私钥文件而不是PEM来解密?

    使用 Java 和 Bouncy Castle 1 52 我可以使用以下代码通过 PEM 证书加载私钥 我还有一个相同的 PKCS8 格式的 private key 文件 直接使用private key文件而不是PEM的代码是什么 Stri
  • 在 C# 中解析 Cryptocompare API Json 数据

    我正在加载数据 这是返回 Response Success Type 100 Aggregated false Data time 1504979760 high 14 26 low 14 26 open 14 26 volumefrom
  • 在节点上生成 AES 密钥

    我正在处理一个使用自定义协议来加密通信的遗留应用程序 随机 AES 密钥在旧版 Java 应用程序中生成 如下所示 keygen KeyGenerator getInstance AES keygen init 128 keygen gen
  • Qt 计算和比较密码哈希

    目前正在 Qt 中为测验程序构建面向 Web 的身份验证服务 据我了解 在数据库中存储用户密码时 必须对其进行隐藏 以防落入坏人之手 流行的方法似乎是添加的过程Salt https en wikipedia org wiki Salt cr
  • 在同步函数中使用 javascript `crypto.subtle`

    在javascript中 是否可以使用浏览器内置的sha256哈希 https developer mozilla org en US docs Web API SubtleCrypto digest Converting a digest
  • 如何将 pem 公钥转换为 openssl RSA* 结构

    假设我必须像这样公开 pem 密钥 BEGIN PUBLIC KEY MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vbqajDw4o6gJy8UtmIbkcpnk O3Kwc4qsEnSZp TR fQi
  • 将公钥从其他地方导入到 CngKey?

    我正在寻找一种跨平台的方式来共享 ECDSA 签名的公钥 从性能角度来看 我对 CngKey 和标准 NET 加密库感到非常高兴 但后来我无法弄清楚 33 或 65 字节公钥 使用 secp256r1 P256 如何变成 104 字节由 M
  • RSACryptoServiceProvider 使用自己的公钥和私钥进行加密和解密

    据我所知 对于非对称加密 您可以使用公钥加密明文并使用私钥解密 所以我尝试了以下方法 static void Main string args RSACryptoServiceProvider rsa new RSACryptoServic
  • 如何加载椭圆曲线 PEM 编码的私钥? [复制]

    这个问题在这里已经有答案了 我使用 OpenSSL 生成了椭圆曲线私钥 公钥对 私钥和公钥均采用 PEM 编码 我已经弄清楚如何加载公钥 感谢this https stackoverflow com a 40439081但是 我无法弄清楚如
  • Java Web Start 的证书已过期

    JWS 对代码签名证书过期有何反应 根据我的观察 它似乎忽略了 CA 签名证书的到期日期 但我想找到一些确凿的证据 例如官方文档 来证实这一点 如果签名的 jar 被赋予时间戳 来自时间戳权威 那么即使在证书过期之后签名仍然有效 假设时间戳
  • Rfc2898DeriveBytes + PBKDF2 + SecureString 是否可以使用安全字符串代替字符串?

    我有一个功能GetPassword 返回一个SecureString type 当我将此安全字符串传递给Rfc2898DeriveBytes生成密钥时 Visual Studio 显示错误 我有限的知识告诉我 这是因为Rfc2898Deri
  • 将列表传递给 PyCrypto 中的 AES 密钥生成器

    我尝试使用 Pycrypto 生成 AES 密钥 但收到以下错误 类型错误 列表 不支持缓冲区接口 对于以下声明 aescipher AES new mykey AES MODE ECB mykey 属于类型list并包含 18854347
  • 在 React Native 和 Expo 中加密敏感数据

    我正在使用 React Native 开发一个移动应用程序Expo https expo io 提供安全解决方案 项目所有者希望在应用程序中存储敏感的授权密钥 用于与 REST 服务器通信并访问安全数据 他要求这些密钥至少是加密的 并且尽可
  • 让 java IAIK PKCS11 包装器适用于 nfast

    我正在尝试让 IAIK PKCS11 包装器与 nfast 一起使用 它总是期待 pkcs11wrapper 库文件并抛出错误 java lang UnsatisfiedLinkError pkcs11wrapper 在java libra
  • 以编程方式添加数字签名外观?

    我正在以编程方式对我的 PDF 文件进行签名 并且我想将签名外观添加到 PDF 我需要哪些对象才能实现此目的 我知道我必须Annotations BBox and XObject但我真的不知道按什么顺序以及是否需要其他东西 调试此类内容以找
  • 在 .Net Core 上使用非对称密钥

    我正在尝试运行此示例中的代码 https learn microsoft com en us dotnet standard security how to store asymmetric keys in a key container
  • 将大数字转换为字母(然后再转换回来)

    是否有一个术语来描述将大数字存储为字母的想法 例如 假设我有 相对较小的 数字 138201162401719 并且我想将字符数缩小到尽可能少的字符数 我知道这无助于节省磁盘空间 英文字母表中有 26 个字母 但我将它们算作 25 个 因为
  • 对 Java 安全性和 BouncyCastle API 感到茫然和困惑

    我一直在尝试理解 Java 的 BouncyCastle 加密 API 不幸的是 我发现 Java 密码学总体上被服务提供者接口和术语所掩盖 以至于我无法理解任何东西的实际作用 我已经尝试反复阅读必要的文档 但它仍然难以理解 引入了许多远远
  • 在 C# 中创建我的对称密钥

    一直在审查一些对称加密方法 我看到了很多在类中硬编码私有静态变量的示例 通常类似于 string key THISISYOURENCRYPTIONKEY 然后在更远的地方 代码使用它来加密 解密 抛开正确的实现 算法 策略以及存储它的位置
  • 在nodejs中解密.Net cookie

    我在 Net 中创建了一个加密的cookie 并尝试在nodejs 中解密它的内容 但是nodejs不断抛出异常 TypeError DecipherFinal失败 在 Net中 我使用带有密钥的AES加密方法 932D86BB1448EE

随机推荐

  • 行指针(对二维数组,多维数组的深层理解)

    行指针 定义 对二维数组的理解 多维数组的理解 二维数组 多维数组向函数传递参数 二维数组 三维数组 定义 声明行指针的语法 数据类型 行指针名 行的大小 行的大小即数组长度 int p1 3 p1是行指针 用于指向数组长度为3的int型数
  • 【周末闲谈】文心一言,模仿还是超越?

    个人主页 个人主页 系列专栏 周末闲谈 周末闲谈 第一周 二进制VS三进制 文章目录 周末闲谈 前言 一 背景环境 二 文心一言 三 文心一言的优势 四 文心一言能否为百度止颓 五 总结 前言 经过了一周的忙碌 周末如期而至 今天我们来聊聊
  • 如何写简历,Web前端简历

    面试官到底想看什么样的简历 面试一直是程序员跳槽时期非常热门的话题 虽然现在已经过了跳槽的旺季 下一轮跳槽需要年底才会出现 但是当跳槽季的时候你再看这篇文章可能已经晚了 过冬的粮食永远不是冬天准备的 而是秋收的时候 点个关注 点个收藏 需要
  • 【计算机视觉

    文章目录 一 GreedyNAS C 二 RegionViT 三 DenseNAS B 四 DenseNAS C 五 DiCENet 六 uNetXST 七 CSPPeleeNet 八 PocketNet 九 OODformer 十 Dee
  • 红外热成像+可见光双光可融合单IP相机

    红外和可见光同时拍摄双光单IP相机可为无人机 机器人 科研机构等提供可靠的视觉效果和数据分析 相机参数可实现定制化服务 让项目达到最佳效果 常规参数如下 相机双光图像单IP输出 可实现视频图像无缝融合 不仅能够看得清 还能看得准 相机数据可
  • android 点击浏览大图,一个图片浏览器,支持超大图、超长图 BigImageViewPager

    BigImage ImageView ViewPager BigImageViewPager 一个图片浏览器 支持超大图 超长图 支持手势放大 支持查看原图 下载 加载百分比进度显示 采用区块复用加载 优化内存占用 有效避免OOM 截图 功
  • Stream调试

    java的stream即流式处理 编码十分简洁 但是却给调试带来了极大的不便 idea推出了streamtrace功能 可以详细看到每一步操作的关系 结果 非常方便进行调试 初遇StreamTrace 这里简单将字符串转成它的字符数 并设置
  • 银屑病药物争相涌现,将惠及国内600万以上银屑病患者

    origin https www jiemian com article 3629136 html 生物制剂在重度银屑病患者中 清除率高且副作用小 但要如何增加可及性 金淼Jemma 2019 10 30 10 44浏览 2 9w来源 界面
  • 【滑动窗口】算法实战

    文章目录 一 算法原理 二 算法实战 1 leetcode209 长度最小的子数组 2 leetcode3 无重复字符的最长子串 3 leetcode1004 最大连续1的个数 4 leetcode1685 将x减到0的最小操作数 5 le
  • log4j中appender的简介说明

    转自 log4j中appender的简介说明 下文笔者将讲述log4j中的appender的简介说明 如下所示 log4j的appender的功能 log4j中appender的功能 用于定义输出文件的方式 有以下5种输出方式可定义 1 o
  • java使用jsch连接ssh远程服务器

    java这边没有很好的封装工具连接ssh jsch使用起来只是略微方便一点 使用的时候可以封装成工具自己使用 jsch有2种方式和客户端进行交互 ChannelShell和ChannelExec ChannelShell和ChannelEx
  • 初级教程之---delphi调试

    一 准备调试 Delphi 在 IDE 内部集成了一个调试器 因而对程序的调试不用离开集成开发环境 IDE 就可以进行 该调试器能够控制程序的运行 监视程序的输出 检查和修改变量的值 在调试程序之前 必须保证程序代码已经没有语法错误 还要正
  • javaweb知识点总结(黑马视频笔记)

    目录 什么是JavaWeb Web JavaWeb JavaWeb技术栈 JDBC简介 概念 本质 快速入门 步骤 API详解 DriverManager Connection Statement ResultSet PreparedSta
  • 第三十七章、PyQt输入部件:QAbstractSlider派生类QScrollBar滚动条、QSlider滑动条、QDial刻度盘功能介绍

    专栏 Python基础教程目录 专栏 使用PyQt开发图形界面Python应用 专栏 PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一 引言 Designer中的输入部件Horizontal ScrollBar水平滚动条
  • LayUI table 刷新页面不重置页码

    layui table 刷新页面时会自动将页码初始化成1 本章内容介绍怎么让layui table刷新页面后留在当前页 要实现此方法主要使用到cookie存储最后一次翻页的页码 主要修改layui lay modules table js文
  • 华为OD机试 - 阿里巴巴找黄金宝箱(V)(Java & JS & Python)

    题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上 无意中发现了强盗集团的藏宝地 藏宝地有编号从0 N的箱子 每个箱子上面贴有一个数字 阿里巴巴念出一个咒语数字k k
  • Android开发:shape和selector和layer-list的(详细说明)

    http blog csdn net brokge article details 9713041
  • 2PSK相干解调电路设计SystemView仿真

    PSK 二进制移相键控方式 是键控的载波相位按基带脉冲序列的规律而改变的一种数字调制方式 就是根据数字基带信号的两个电平 或符号 使载波相位在两个不同的数值之间切换的一种相位调制方法 两个载波相位通常相差180度 此时称为反向键控 PSK
  • Linux下的文件编辑实验

    实验内容 掌握文件管理的一些基本命令 head tail grep cp useradd groupadd passwd gpasswd tar 实验内容 1 查看 etc passwd文件的第18 20行内容 并将找到的内容存储至 hom
  • SM2公钥加密

    文章目录 简介 推荐参数 1 前置条件 1 1 点到字符串的转换 压缩 未压缩 混合形式 1 2 密钥派生函数 6 加解密 加密流程 解密流程 实现 参考资料 简介 国密SM2算法并不仅仅是提供了新的曲线参数 而是在算法上对ECC进行了修改