c语言ecc
非对称加密需要两个密钥:公钥(publickey) 和私钥 (privatekey)。公钥和私钥是一对,如果用公钥对数据加密,那么只能用对应的私钥解密。如果用私钥对数据加密,只能用对应的公钥进行解密。因为加密和解密用的是不同的密钥,所以称为非对称加密。
非对称加密算法的保密性好,它消除了最终用户交换密钥的需要。但是加解密速度要远远慢于对称加密,在某些极端情况下,甚至能比对称加密慢上1000倍。
算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。对称密码体制中只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥。所以保证其安全性就是保证密钥的安全,而非对称密钥体制有两种密钥,其中一个是公开的,这样就可以不需要像对称密码那样传输对方的密钥了。这样安全性就大了很多。
RSA、Elgamal、背包算法、Rabin、D-H、ECC (椭圆曲线加密算法)。使用最广泛的是 RSA 算法,Elgamal 是另一种常用的非对称加密算法。
收信者是唯一能够解开加密信息的人,因此收信者手里的必须是私钥。发信者手里的是公钥,其它人知道公钥没有关系,因为其它人发来的信息对收信者没有意义。
客户端需要将认证标识传送给服务器,此认证标识 (可能是一个随机数) 其它客户端可以知道,因此需要用私钥加密,客户端保存的是私钥。服务器端保存的是公钥,其它服务器知道公钥没有关系,因为客户端不需要登录其它服务器。
数字签名是为了表明信息没有受到伪造,确实是信息拥有者发出来的,附在信息原文的后面。就像手写的签名一样,具有不可抵赖性和简洁性。
简洁性:对信息原文做哈希运算,得到消息摘要,信息越短加密的耗时越少。
不可抵赖性:信息拥有者要保证签名的唯一性,必须是唯一能够加密消息摘要的人,因此必须用私钥加密 (就像字迹他人无法学会一样),得到签名。如果用公钥,那每个人都可以伪造签名了。
问题起源:对1和3,发信者怎么知道从网上获取的公钥就是真的?没有遭受中间人攻击?
这样就需要第三方机构来保证公钥的合法性,这个第三方机构就是 CA (Certificate Authority),证书中心。
CA 用自己的私钥对信息原文所有者发布的公钥和相关信息进行加密,得出的内容就是数字证书。
信息原文的所有者以后发布信息时,除了带上自己的签名,还带上数字证书,就可以保证信息不被篡改了。信息的接收者先用 CA给的公钥解出信息所有者的公钥,这样可以保证信息所有者的公钥是真正的公钥,然后就能通过该公钥证明数字签名是否真实了。
RSA 是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用。
A 要把信息发给 B 为例,确定角色:A 为加密者,B 为解密者。首先由 B 随机确定一个 KEY,称之为私钥,将这个 KEY 始终保存在机器 B 中而不发出来;然后,由这个 KEY 计算出另一个 KEY,称之为公钥。这个公钥的特性是几乎不可能通过它自身计算出生成它的私钥。接下来通过网络把这个公钥传给 A,A 收到公钥后,利用公钥对信息加密,并把密文通过网络发送到 B,最后 B 利用已知的私钥,就能对密文进行解码了。以上就是 RSA 算法的工作流程。
由于进行的都是大数计算,使得 RSA 最快的情况也比 DES 慢上好几倍,无论是软件还是硬件实现。速度一直是 RSA 的缺陷。一般来说只用于少量数据加密。RSA 的速度是对应同样安全级别的对称密码算法的1/1000左右。
比起 DES 和其它对称算法来说,RSA 要慢得多。实际上一般使用一种对称算法来加密信息,然后用 RSA 来加密比较短的公钥,然后将用 RSA 加密的公钥和用对称算法加密的消息发送给接收方。
这样一来对随机数的要求就更高了,尤其对产生对称密码的要求非常高,否则的话可以越过 RSA 来直接攻击对称密码。
和其它加密过程一样,对 RSA 来说分配公钥的过程是非常重要的。分配公钥的过程必须能够抵挡中间人攻击。假设 A 交给 B 一个公钥,并使 B 相信这是A 的公钥,并且 C 可以截下 A 和 B 之间的信息传递,那么 C 可以将自己的公钥传给 B,B 以为这是 A 的公钥。C 可以将所有 B 传递给 A 的消息截下来,将这个消息用自己的密钥解密,读这个消息,然后将这个消息再用 A 的公钥加密后传给 A。理论上 A 和 B 都不会发现 C 在偷听它们的消息,今天人们一般用数字认证来防止这样的攻击。
(1) 针对 RSA 最流行的攻击一般是基于大数因数分解。1999年,RSA-155 (512 bits) 被成功分解,花了五个月时间(约8000 MIPS 年)和224 CPU hours 在一台有3.2G 中央内存的 Cray C916计算机上完成。
RSA-158 表示如下:
2009年12月12日,编号为 RSA-768 (768 bits, 232 digits) 数也被成功分解。这一事件威胁了现通行的1024-bit 密钥的安全性,普遍认为用户应尽快升级到2048-bit 或以上。
RSA-768表示如下:
(2) 秀尔算法
量子计算里的秀尔算法能使穷举的效率大大的提高。由于 RSA 算法是基于大数分解 (无法抵抗穷举攻击),因此在未来量子计算能对 RSA 算法构成较大的威胁。一个拥有 N 量子位的量子计算机,每次可进行2^N 次运算,理论上讲,密钥为1024位长的 RSA 算法,用一台512量子比特位的量子计算机在1秒内即可破解。
DSA (Digital Signature Algorithm) 是 Schnorr 和 ElGamal 签名算法的变种,被美国 NIST 作为 DSS (DigitalSignature Standard)。 DSA 是基于整数有限域离散对数难题的。
简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名,如果数据和签名不匹配则认为验证失败。数字签名的作用就是校验数据在传输过程中不被修改,数字签名,是单向加密的升级。
椭圆加密算法(ECC)是一种公钥加密算法,最初由 Koblitz 和 Miller 两人于1985年提出,其数学基础是利用椭圆曲线上的有理点构成 Abel 加法群上椭圆离散对数的计算困难性。公钥密码体制根据其所依据的难题一般分为三类:大整数分解问题类、离散对数问题类、椭圆曲线类。有时也把椭圆曲线类归为离散对数类。
ECC 的主要优势是在某些情况下它比其他的方法使用更小的密钥 (比如 RSA),提供相当的或更高等级的安全。ECC 的另一个优势是可以定义群之间的双线性映射,基于 Weil 对或是 Tate 对;双线性映射已经在密码学中发现了大量的应用,例如基于身份的加密。不过一个缺点是加密和解密操作的实现比其他机制花费的时间长。
ECC 被广泛认为是在给定密钥长度的情况下,最强大的非对称算法,因此在对带宽要求十分紧的连接中会十分有用。
比特币钱包公钥的生成使用了椭圆曲线算法,通过椭圆曲线乘法可以从私钥计算得到公钥, 这是不可逆转的过程。
https://github.com/esxgx/easy-ecc
Java 中 Chipher、Signature、KeyPairGenerator、KeyAgreement、SecretKey 均不支持 ECC 算法。
https://www.jianshu.com/p/58c1750c6f22
DH,全称为"Diffie-Hellman",它是一种确保共享 KEY 安全穿越不安全网络的方法,也就是常说的密钥一致协议。由公开密钥密码体制的奠基人 Diffie 和 Hellman 所提出的一种思想。简单的说就是允许两名用户在公开媒体上交换信息以生成"一致"的、可以共享的密钥。也就是由甲方产出一对密钥 (公钥、私钥),乙方依照甲方公钥产生乙方密钥对 (公钥、私钥)。
以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥 (SecretKey) 对数据加密。这样,在互通了本地密钥 (SecretKey) 算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。不单单是甲乙双方两方,可以扩展为多方共享数据通讯,这样就完成了网络交互数据的安全通讯。
具体例子可以移步到这篇文章: 非对称密码之DH密钥交换算法
参考:
https://blog.csdn.net/u014294681/article/details/86705999
https://www.cnblogs.com/wangzxblog/p/13667634.html
https://www.cnblogs.com/taoxw/p/15837729.html
https://www.cnblogs.com/fangfan/p/4086662.html
https://www.cnblogs.com/utank/p/7877761.html
https://blog.csdn.net/m0_59133441/article/details/122686815
https://www.cnblogs.com/muliu/p/10875633.html
https://www.cnblogs.com/wf-zhang/p/14923279.html
https://www.jianshu.com/p/7a927db713e4
https://blog.csdn.net/ljx1400052550/article/details/79587133
https://blog.csdn.net/yuanjian0814/article/details/109815473
‘贰’ 求一个基于openssl写的ecc曲线的源代码
下面的例子生成两对ECC密钥,并用它做签名和验签,并生成共享密钥。
#include <string.h>
#include <stdio.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/objects.h>
#include <openssl/err.h>
int main()
{
EC_KEY *key1,*key2;
EC_POINT *pubkey1,*pubkey2;
EC_GROUP *group1,*group2;
int ret,nid,size,i,sig_len;
unsigned char*signature,digest[20];
BIO *berr;
EC_builtin_curve *curves;
int crv_len;
char shareKey1[128],shareKey2[128];
int len1,len2;
/* 构造EC_KEY数据结构 */
key1=EC_KEY_new();
if(key1==NULL)
{
printf("EC_KEY_new err!\n");
return -1;
}
key2=EC_KEY_new();
if(key2==NULL)
{
printf("EC_KEY_new err!\n");
return -1;
}
/* 获取实现的椭圆曲线个数 */
crv_len = EC_get_builtin_curves(NULL, 0);
curves = (EC_builtin_curve *)malloc(sizeof(EC_builtin_curve) * crv_len);
/* 获取椭圆曲线列表 */
EC_get_builtin_curves(curves, crv_len);
/*
nid=curves[0].nid;会有错误,原因是密钥太短
*/
/* 选取一种椭圆曲线 */
nid=curves[25].nid;
/* 根据选择的椭圆曲线生成密钥参数group */
group1=EC_GROUP_new_by_curve_name(nid);
if(group1==NULL)
{
printf("EC_GROUP_new_by_curve_name err!\n");
return -1;
}
group2=EC_GROUP_new_by_curve_name(nid);
if(group1==NULL)
{
printf("EC_GROUP_new_by_curve_name err!\n");
return -1;
}
/* 设置密钥参数 */
ret=EC_KEY_set_group(key1,group1);
if(ret!=1)
{
printf("EC_KEY_set_group err.\n");
return -1;
}
ret=EC_KEY_set_group(key2,group2);
if(ret!=1)
{
printf("EC_KEY_set_group err.\n");
return -1;
}
/* 生成密钥 */
ret=EC_KEY_generate_key(key1);
if(ret!=1)
{
printf("EC_KEY_generate_key err.\n");
return -1;
}
ret=EC_KEY_generate_key(key2);
if(ret!=1)
{
printf("EC_KEY_generate_key err.\n");
return -1;
}
/* 检查密钥 */
ret=EC_KEY_check_key(key1);
if(ret!=1)
{
printf("check key err.\n");
return -1;
}
/* 获取密钥大小 */
size=ECDSA_size(key1);
printf("size %d \n",size);
for(i=0;i<20;i++)
memset(&digest[i],i+1,1);
signature=malloc(size);
ERR_load_crypto_strings();
berr=BIO_new(BIO_s_file());
BIO_set_fp(berr,stdout,BIO_NOCLOSE);
/* 签名数据,本例未做摘要,可将digest中的数据看作是sha1摘要结果 */
ret=ECDSA_sign(0,digest,20,signature,&sig_len,key1);
if(ret!=1)
{
ERR_print_errors(berr);
printf("sign err!\n");
return -1;
}
/* 验证签名 */
ret=ECDSA_verify(0,digest,20,signature,sig_len,key1);
if(ret!=1)
{
ERR_print_errors(berr);
printf("ECDSA_verify err!\n");
return -1;
}
/* 获取对方公钥,不能直接引用 */
pubkey2 = EC_KEY_get0_public_key(key2);
/* 生成一方的共享密钥 */
len1=ECDH_compute_key(shareKey1, 128, pubkey2, key1, NULL);
pubkey1 = EC_KEY_get0_public_key(key1);
/* 生成另一方共享密钥 */
len2=ECDH_compute_key(shareKey2, 128, pubkey1, key2, NULL);
if(len1!=len2)
{
printf("err\n");
}
else
{
ret=memcmp(shareKey1,shareKey2,len1);
if(ret==0)
printf("生成共享密钥成功\n");
else
printf("生成共享密钥失败\n");
}
printf("test ok!\n");
BIO_free(berr);
EC_KEY_free(key1);
EC_KEY_free(key2);
free(signature);
free(curves);
return 0;
}
‘叁’ 服务器百问百答,服务器的ECC技术指的是什么
ECC是“Error Checking and Correcting”的简写,中文名称是“错误检查和纠正”。ECC是一种能够实现“错误检查和纠正”的技术,ECC内存就是应用了这种技术的内存,一般多应用在服务器及图形工作站上,这将使整个电脑系统在工作时更趋于安全稳定。
要了解ECC技术,就不能不提到Parity(奇偶校验)。在ECC技术出现之前,内存中应用最多的是另外一种技术,就是Parity(奇偶校验)。我们知道,在数字电路中,最小的数据单位就是叫“比特(bit)”,也叫数据“位”,“比特”也是内存中的最小单位,它是通过“1”和“0”来表示数据高、低电平信号的。在数字电路中8个连续的比特是一个字节(byte),在内存中不带“奇偶校验”的内存中的每个字节只有8位,若它的某一位存储出了错误,就会使其中存储的相应数据发生改变而导致应用程序发生错误。而带有“奇偶校验”的内存在每一字节(8位)外又额外增加了一位用来进行错误检测。比如一个字节中存储了某一数值(1、0、1、0、1、0、1、1),把这每一位相加起来(1+0+1+0+1+0+1+1=5)。若其结果是奇数,对于偶校验,校验位就定义为1,反之则为0;对于奇校验,则相反。当CPU返回读取存储的数据时,它会再次相加前8位中存储的数据,计算结果是否与校验位相一致。当CPU发现二者不同时就作出视图纠正这些错误,但Parity有个缺点,当内存查到某个数据位有错误时,却并不一定能确定在哪一个位,也就不一定能修正错误,所以带有奇偶校验的内存的主要功能仅仅是“发现错误”,并能纠正部分简单的错误。
通过上面的分析我们知道Parity内存是通过在原来数据位的基础上增加一个数据位来检查当前8位数据的正确性,但随着数据位的增加Parity用来检验的数据位也成倍增加,就是说当数据位为16位时它需要增加2位用于检查,当数据位为32位时则需增加4位,依此类推。特别是当数据量非常大时,数据出错的几率也就越大,对于只能纠正简单错误的奇偶检验的方法就显得力不从心了,正是基于这样一种情况,一种新的内存技术应允而生了,这就是ECC(错误检查和纠正),这种技术也是在原来的数据位上外加校验位来实现的。不同的是两者增加的方法不一样,这也就导致了两者的主要功能不太一样。它与Parity不同的是如果数据位是8位,则需要增加5位来进行ECC错误检查和纠正,数据位每增加一倍,ECC只增加一位检验位,也就是说当数据位为16位时ECC位为6位,32位时ECC位为7位,数据位为64位时ECC位为8位,依此类推,数据位每增加一倍,ECC位只增加一位。总之,在内存中ECC能够容许错误,并可以将错误更正,使系统得以持续正常的操作,不致因错误而中断,且ECC具有自动更正的能力,可以将Parity无法检查出来的错误位查出并将错误修正。
2 ECC(Elliptic Curve Cryptosystems )椭圆曲线密码体制
2002年,美国SUN公司将其开发的椭圆加密技术赠送给开放源代码工程
公钥密码体制根据其所依据的难题一般分为三类:大整数分解问题类、离散对数问题类、椭圆曲线类。有时也把椭圆曲线类归为离散对数类。
椭圆曲线密码体制来源于对椭圆曲线的研究,所谓椭圆曲线指的是由韦尔斯特拉斯(Weierstrass)方程:
y2+a1xy+a3y=x3+a2x2+a4x+a6 (1)
所确定的平面曲线。其中系数ai(I=1,2,…,6)定义在某个域上,可以是有理数域、实数域、复数域,还可以是有限域GF(pr),椭圆曲线密码体制中用到的椭圆曲线都是定义在有限域上的。
椭圆曲线上所有的点外加一个叫做无穷远点的特殊点构成的集合连同一个定义的加法运算构成一个Abel群。在等式
mP=P+P+…+P=Q (2)
中,已知m和点P求点Q比较容易,反之已知点Q和点P求m却是相当困难的,这个问题称为椭圆曲线上点群的离散对数问题。椭圆曲线密码体制正是利用这个困难问题设计而来。椭圆曲线应用到密码学上最早是由Neal Koblitz 和Victor Miller在1985年分别独立提出的。
椭圆曲线密码体制是目前已知的公钥体制中,对每比特所提供加密强度最高的一种体制。解椭圆曲线上的离散对数问题的最好算法是Pollard rho方法,其时间复杂度为,是完全指数阶的。其中n为等式(2)中m的二进制表示的位数。当n=234, 约为2117,需要1.6x1023 MIPS 年的时间。而我们熟知的RSA所利用的是大整数分解的困难问题,目前对于一般情况下的因数分解的最好算法的时间复杂度是子指数阶的,当n=2048时,需要2x1020MIPS年的时间。也就是说当RSA的密钥使用2048位时,ECC的密钥使用234位所获得的安全强度还高出许多。它们之间的密钥长度却相差达9倍,当ECC的密钥更大时它们之间差距将更大。更ECC密钥短的优点是非常明显的,随加密强度的提高,密钥长度变化不大。
德国、日本、法国、美国、加拿大等国的很多密码学研究小组及一些公司实现了椭圆曲线密码体制,我国也有一些密码学者做了这方面的工作。许多标准化组织已经或正在制定关于椭圆曲线的标准,同时也有许多的厂商已经或正在开发基于椭圆曲线的产品。对于椭圆曲线密码的研究也是方兴未艾,从ASIACRYPTO’98上专门开辟了ECC的栏目可见一斑。
在椭圆曲线密码体制的标准化方面,IEEE、ANSI、ISO、IETF、ATM等都作了大量的工作,它们所开发的椭圆曲线标准的文档有:IEEE P1363 P1363a、ANSI X9.62 X9.63、 ISO/IEC14888等。
2003年5月12日中国颁布的无线局域网国家标准 GB15629.11 中,包含了全新的WAPI(WLAN Authentication and Privacy Infrastructure)安全机制,能为用户的WLAN系统提供全面的安全保护。这种安全机制由 WAI和WPI两部分组成,分别实现对用户身份的鉴别和对传输的数据加密。WAI采用公开密钥密码体制,利用证书来对WLAN系统中的用户和AP进行认证。证书里面包含有证书颁发者(ASU)的公钥和签名以及证书持有者的公钥和签名,这里的签名采用的就是椭圆曲线ECC算法。
加拿大Certicom公司是国际上最着名的ECC密码技术公司,已授权300多家企业使用ECC密码技术,包括Cisco 系统有限公司、摩托罗拉、Palm等企业。Microsoft将Certicom公司的VPN嵌入微软视窗移动2003系统中。
ECC :engine control center发动机控制中心,主要适用于民航
ECC :ERP Central Componet, 企业资源计划核心组件(参考资源SAP教程)
3 ECC: Embedded Control Channel 嵌入控制信道
SDH网络中的ECC是传送操作、管理和维护(OAMP)信息的逻辑信道。它以SDH中的数据通信信道(DCC)作为其物理通路。SDH ECC 协议栈是以OSI参考模型为基础的,协议的设计方法与当前管理系统的面向对象是一致的。ECC协 议栈的应用层包含公共管理信息服务单元(CMISE),还包含支持CMICE的远程操作服务单元(ROSE)和联系控制服务单元(ACSE)。表示层、会 话层和传送层提供支持ROSE和ACSE所需的面向连接的服务。其中传送层还包括附加协议单元,使得在由无连接网络层协议(CLNP)操作时可提供连接模 式服务。数据链路层采用Q.920和Q.921中所规定的D信道链路接入程序(LAPD),物理通路采用SDH DCC。
‘肆’ 姹傝茶ВECC锛 128浣嶆暟鎹浣嶏纴9浣嶆牎楠屼綅镄勭畻娉
ECC锛圗rror Correction Code锛夋槸涓绉岖敤𨱒ユ娴嫔拰绾犳e唴瀛树腑镄勬暟鎹阌栾镄勬妧链锛屽畠鍙浠ユ彁楂樼郴缁熺殑鍙闱犳у拰绋冲畾镐с侲CC浣跨敤涓绉嶆洿楂樼骇镄勫囧伓镙¢獙鏂规硶锛屽嵆瀵规疮64浣嶆暟鎹鐢熸垚7浣嶆牎楠屼綅锛岀劧钖庢牴鎹杩欎簺镙¢獙浣嶆潵鍒ゆ柇鏁版嵁鏄钖﹀彂鐢熶简阌栾锛屼互鍙婂备綍淇澶嶉敊璇銆
鐢–璇瑷缂栧啓涓涓128浣嶆暟鎹浣嶏纴9浣嶆牎楠屼綅镄凟CC绠楁硶锛岄渶瑕佷互涓嫔嚑涓姝ラわ细
瀹氢箟涓涓缁撴瀯浣掳纴琛ㄧず涓涓128浣岖殑鏁版嵁瀛楋纴浠ュ强涓涓9浣岖殑镙¢獙瀛椼傛垜浠鍙浠ヤ娇鐢ㄤ竴涓闀垮害涓4镄勬棤绗﹀彿鏁村瀷鏁扮粍𨱒ュ瓨鍌ㄦ暟鎹瀛楋纴姣忎釜鍏幂礌鍗32浣嶏纴鍏辫128浣嶃傛垜浠鍙浠ヤ娇鐢ㄤ竴涓镞犵﹀彿瀛楃︽潵瀛桦偍镙¢獙瀛楋纴鍗8浣嶏纴鍐嶅姞涓娄竴涓甯冨皵鍊兼潵琛ㄧず绗9浣嶏纴鍏辫9浣嶃
瀹氢箟涓涓鍑芥暟锛屾牴鎹缁椤畾镄勬暟鎹瀛楃敓鎴愬瑰簲镄勬牎楠屽瓧銆傛垜浠鍙浠ヤ娇鐢ㄥ纾鎴栬繍绠楁潵璁$畻姣忎竴浣岖殑濂囧伓镙¢獙鍊硷纴铹跺悗灏呜繖浜涘肩粍钖堟垚涓涓镙¢獙瀛椼
瀹氢箟涓涓鍑芥暟锛屾牴鎹缁椤畾镄勬暟鎹瀛楀拰镙¢獙瀛楁娴嬫槸钖︽湁阌栾鍙戠敓銆傛垜浠鍙浠ヤ娇鐢ㄥ纾鎴栬繍绠楁潵姣旇缉鏁版嵁瀛楀拰镙¢獙瀛椾腑镄勬疮涓浣嶏纴濡傛灉链変笉钖岋纴鍒栾存槑链夐敊璇鍙戠敓銆傛垜浠鍙浠ヤ娇鐢ㄤ竴涓鏁村瀷鍙橀噺𨱒ヨ板綍阌栾鍙戠敓镄勪綅缃锛屽傛灉娌℃湁阌栾锛屽垯杩斿洖-1銆
瀹氢箟涓涓鍑芥暟锛屾牴鎹缁椤畾镄勬暟鎹瀛楀拰阌栾浣岖疆淇澶嶉敊璇銆傛垜浠鍙浠ヤ娇鐢ㄥ纾鎴栬繍绠楁潵缈昏浆鏁版嵁瀛椾腑鍑洪敊镄勯偅涓浣嶏纴浠庤屾仮澶嶆g‘镄勫笺
‘伍’ 国密算法
国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。
SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。
国家密码管理局公布的公钥算法,其加密强度为256位
SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。
由于SM1、SM4加解密的分组大小为128bit,故对消息进行加解密时,若消息长度过长,需要进行分组,要消息长度不足,则要进行填充。
分组密码算法(DES和SM4)、将明文数据按固定长度进行分组,然后在同一密钥控制下逐组进行加密,
公钥密码算法(RSA和SM2)、公开加密算法本身和公开公钥,保存私钥
摘要算法(SM3 md5) 这个都比较熟悉,用于数字签名,消息认证,数据完整性,但是sm3安全度比md5高
总得来说国密算法的安全度比较高,2010年12月推出,也是国家安全战略,现在银行都要要求国际算法改造,要把国际算法都给去掉
C 语言实现
https://github.com/guan/GmSSL/
Go 语言
https://github.com/tjfoc/gmsm
https://github.com/ZZMarquis/gm
Java 语言
https://github.com/PopezLotado/SM2Java
Go语言实现,调用 gmsm
‘陆’ c语言常用函数有哪些主要掌握的要点是什么
标准头文件包括:
<asset.h> <ctype.h> <errno.h> <float.h>
<limits.h> <locale.h> <math.h> <setjmp.h>
<signal.h> <stdarg.h> <stddef.h> <stdlib.h>
<stdio.h> <string.h> <time.h>
一、标准定义(<stddef.h>)
文件<stddef.h>里包含了标准库的一些常用定义,无论我们包含哪个标准头文件,<stddef.h>都会被自动包含进来。
这个文件里定义:
l 类型size_t (sizeof运算符的结果类型,是某个无符号整型);
l 类型ptrdiff_t(两个指针相减运算的结果类型,是某个有符号整型);
l 类型wchar_t (宽字符类型,是一个整型,其中足以存放本系统所支持的所有本地环境中的字符集的所有编码值。这里还保证空字符的编码值为0);
l 符号常量NULL (空指针值);
l 宏offsetor (这是一个带参数的宏,第一个参数应是一个结构类型,第二个参数应是结构成员名。
offsetor(s,m)求出成员m在结构类型t的变量里的偏移量)。
注:其中有些定义也出现在其他头文件里(如NULL)。
二、错误信息(<errno.h>)
<errno.h>定义了一个int类型的表达式errno,可以看作一个变量,其初始值为0,一些标准库函数执行中出错时将它设为非0值,但任何标准库函数都设置它为0。
<errno.h>里还定义了两个宏EDOM和ERANGE,都是非0的整数值。数学函数执行中遇到参数错误,就会将errno置为EDOM,如出现值域错误就会将errno置为ERANGE。
三、输入输出函数(<stdio.h>)
文件打开和关闭:
FILE *fopen(const char *filename, const char *mode);
int fclose(FILE * stream);
字符输入输出:
int fgetc(FILE *fp);
int fputc(int c, FILE *fp);
getc和putc与这两个函数类似,但通过宏定义实现。通常有下面定义:
#define getchar() getc(stdin)
#define putchar(c) putc(c, stdout)
int ungetc(int c, FILE* stream);//把字符 c 退回流 stream
格式化输入输出:
int scanf(const char *format, ...);
int printf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sscanf(char *s, const char *format, ...);
int sprintf(char *s, const char *format, ...);
行式输入输出:
char *fgets(char *buffer, int n, FILE *stream);
int fputs(const char *buffer, FILE *stream);
char *gets(char *s);
int puts(const char *s);
直接输入输出:
size_t fread(void *pointer, size_t size, size_t num, FILE *stream);
size_t fwrite(const void *pointer, size_t size, size_t num, FILE *stream);