轉(zhuǎn):https://blog.csdn.net/m0_37458552/article/details/80250258
一余爆、ECDSA概述
橢圓曲線數(shù)字簽名算法(ECDSA)是使用橢圓曲線密碼(ECC)對(duì)數(shù)字簽名算法(DSA)的模擬蓬豁。ECDSA于1999年成為ANSI標(biāo)準(zhǔn)尖阔,并于2000年成為IEEE和NIST標(biāo)準(zhǔn)盒音。
它在1998年既已為ISO所接受义辕,并且包含它的其他一些標(biāo)準(zhǔn)亦在ISO的考慮之中卧须。與普通的離散對(duì)數(shù)問題(discrete logarithm problem DLP)和大數(shù)分解問題(integer factorization problem IFP)不同全陨,橢圓曲線離散對(duì)數(shù)問題(elliptic curve discrete logarithm problem ECDLP)沒有亞指數(shù)時(shí)間的解決方法萄传。因此橢圓曲線密碼的單位比特強(qiáng)度要高于其他公鑰體制甚颂。
數(shù)字簽名算法(DSA)在聯(lián)邦信息處理標(biāo)準(zhǔn)FIPS中有詳細(xì)論述蜜猾,稱為數(shù)字簽名標(biāo)準(zhǔn)。它的安全性基于素域上的離散對(duì)數(shù)問題振诬。橢圓曲線密碼(ECC)由Neal Koblitz和Victor Miller于1985年發(fā)明蹭睡。它可以看作是橢圓曲線對(duì)先前基于離散對(duì)數(shù)問題(DLP)的密碼系統(tǒng)的模擬,只是群元素由素域中的元素?cái)?shù)換為有限域上的橢圓曲線上的點(diǎn)赶么。
橢圓曲線密碼體制的安全性基于橢圓曲線離散對(duì)數(shù)問題(ECDLP)的難解性肩豁。橢圓曲線離散對(duì)數(shù)問題遠(yuǎn)難于離散對(duì)數(shù)問題,橢圓曲線密碼系統(tǒng)的單位比特強(qiáng)度要遠(yuǎn)高于傳統(tǒng)的離散對(duì)數(shù)系統(tǒng)辫呻。因此在使用較短的密鑰的情況下清钥,ECC可以達(dá)到于DL系統(tǒng)相同的安全級(jí)別。這帶來的好處就是計(jì)算參數(shù)更小放闺,密鑰更短祟昭,運(yùn)算速度更快,簽名也更加短小怖侦。因此橢圓曲線密碼尤其適用于處理能力篡悟、存儲(chǔ)空間、帶寬及功耗受限的場(chǎng)合匾寝。
二搬葬、ECDSA原理
ECDSA是ECC與DSA的結(jié)合,整個(gè)簽名過程與DSA類似艳悔,所不一樣的是簽名中采取的算法為ECC急凰,最后簽名出來的值也是分為r,s。
簽名過程如下:
1很钓、選擇一條橢圓曲線Ep(a,b)香府,和基點(diǎn)G;
2码倦、選擇私有密鑰k(k
3、產(chǎn)生一個(gè)隨機(jī)整數(shù)r(r
4锭碳、將原數(shù)據(jù)和點(diǎn)R的坐標(biāo)值x,y作為參數(shù)袁稽,計(jì)算SHA1做為hash,即Hash=SHA1(原數(shù)據(jù),x,y)擒抛;
5推汽、計(jì)算s≡r - Hash * k (mod n)
6、r和s做為簽名值歧沪,如果r和s其中一個(gè)為0歹撒,重新從第3步開始執(zhí)行
驗(yàn)證過程如下:
1、接受方在收到消息(m)和簽名值(r,s)后诊胞,進(jìn)行以下運(yùn)算
2暖夭、計(jì)算:sG+H(m)P=(x1,y1), r1≡ x1 mod p。
3、驗(yàn)證等式:r1 ≡ r mod p迈着。
4竭望、如果等式成立,接受簽名裕菠,否則簽名無效咬清。
三、JDK中對(duì)于ECDSA的實(shí)現(xiàn)
特別注意的是:ECDSA簽名算法奴潘,只是在JDK1.7之后才有實(shí)現(xiàn)旧烧,最常見的場(chǎng)景是在微軟的產(chǎn)品的安裝的產(chǎn)品密鑰的設(shè)計(jì)
1、KeyPairGenerator
KeyPairGenerator 類用于生成公鑰和私鑰對(duì)画髓。密鑰對(duì)生成器是使用 getInstance 工廠方法(返回一個(gè)給定類的實(shí)例的靜態(tài)方法)構(gòu)造的粪滤。
特定算法的密鑰對(duì)生成器可以創(chuàng)建能夠與此算法一起使用的公鑰/私鑰對(duì)。它還可以將特定于算法的參數(shù)與每個(gè)生成的密鑰關(guān)聯(lián)雀扶。
有兩種生成密鑰對(duì)的方式:與算法無關(guān)的方式和特定于算法的方式杖小。
下面我們將按照指定ECDSA算法去生成秘鑰KeyPairGenerator.getInstance("EC");
2、ECDSAPublicKey
ECDSA公用密鑰的接口
3愚墓、ECDSAPublicKey
ECDSA 專用密鑰的接口
4予权、PKCS8EncodedKeySpec
PKCS8EncodedKeySpec類繼承EncodedKeySpec類,以編碼格式來表示私鑰浪册。
PKCS8EncodedKeySpec類使用PKCS#8標(biāo)準(zhǔn)作為密鑰規(guī)范管理的編碼格式
5扫腺、Signature
Signature 類用來為應(yīng)用程序提供數(shù)字簽名算法功能。數(shù)字簽名用于確保數(shù)字?jǐn)?shù)據(jù)的驗(yàn)證和完整性村象。
在所有算法當(dāng)中笆环,數(shù)字簽名可以是 NIST 標(biāo)準(zhǔn)的 ECDSA,它使用 ECDSA 和 SHA-1厚者≡炅樱可以將使用 SHA-1 消息摘要算法的 ECDSA 算法指定為SHA1withECDSA。
四库菲、實(shí)現(xiàn)
其中ECDSA的實(shí)現(xiàn)步驟類似于我們之前學(xué)習(xí)的RSA數(shù)字簽名算法账忘。
實(shí)現(xiàn)步驟
第一步:初始化化秘鑰組,生成ECDSA算法的公鑰和私鑰
第二步:執(zhí)行私鑰簽名熙宇, 使用私鑰簽名鳖擒,生成私鑰簽名
第三步:執(zhí)行公鑰簽名,生成公鑰簽名
第四步:使用公鑰驗(yàn)證私鑰簽名
備注:所謂的公鑰與私鑰匙成對(duì)出現(xiàn)烫止。 遵從的原則就是“私鑰簽名蒋荚、公鑰驗(yàn)證”。
示例代碼如下:
importjava.security.KeyFactory;
importjava.security.KeyPair;
importjava.security.KeyPairGenerator;
importjava.security.PrivateKey;
importjava.security.PublicKey;
importjava.security.Signature;
importjava.security.interfaces.ECPrivateKey;
importjava.security.interfaces.ECPublicKey;
importjava.security.spec.PKCS8EncodedKeySpec;
importjava.security.spec.X509EncodedKeySpec;
/**
* 橢圓曲線簽名算法
*
* 速度快 強(qiáng)度高 簽名短
*
* 實(shí)現(xiàn)方 JDK1.7/BC
*/
publicclass ECDSAUtil {
privatestaticStringstr ="hello";
publicstaticvoidmain(String[] args) {
? ? ? ? jdkECDSA();
? ? }
publicstaticvoidjdkECDSA() {
try{
KeyPairGeneratorkeyPairGenerator =KeyPairGenerator.getInstance("EC");
keyPairGenerator.initialize(256);
KeyPairkeyPair = keyPairGenerator.generateKeyPair();
ECPublicKeyecPublicKey = (ECPublicKey) keyPair.getPublic();
ECPrivateKeyecPrivateKey = (ECPrivateKey) keyPair.getPrivate();
// 2.執(zhí)行簽名
PKCS8EncodedKeySpecpkcs8EncodedKeySpec =newPKCS8EncodedKeySpec(ecPrivateKey.getEncoded());
KeyFactorykeyFactory =KeyFactory.getInstance("EC");
PrivateKeyprivateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Signaturesignature =Signature.getInstance("SHA1withECDSA");
? ? ? ? ? ? signature.initSign(privateKey);
? ? ? ? ? ? signature.update(str.getBytes());
? ? ? ? ? ? byte[] sign = signature.sign();
// 驗(yàn)證簽名
X509EncodedKeySpecx509EncodedKeySpec =newX509EncodedKeySpec(ecPublicKey.getEncoded());
keyFactory =KeyFactory.getInstance("EC");
PublicKeypublicKey = keyFactory.generatePublic(x509EncodedKeySpec);
signature =Signature.getInstance("SHA1withECDSA");
? ? ? ? ? ? signature.initVerify(publicKey);
? ? ? ? ? ? signature.update(str.getBytes());
? ? ? ? ? ? boolean bool = signature.verify(sign);
System.out.println(bool);
}catch(Exceptione) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
}
五馆蠕、ECDSA標(biāo)準(zhǔn)
ECDSA的標(biāo)準(zhǔn)和標(biāo)準(zhǔn)草案有很多期升,其中已經(jīng)過頒發(fā)部門批準(zhǔn)的有:ANSI X9.62 ,FIPS 186-2,IEEE 1363-2000,ISO 14888-3惊奇。ECDSA也被密碼標(biāo)準(zhǔn)化組織(SECG,這是一個(gè)從事密碼標(biāo)準(zhǔn)通用性潛力研究的組織)加以標(biāo)準(zhǔn)化吓妆。
主要的ECDSA標(biāo)準(zhǔn)如下:
1.ANSI X9.62
該項(xiàng)目始于1995年赊时,并于1999年正式作為ANSI標(biāo)準(zhǔn)頒布。ANSI X9.62具有高安全性和通用性行拢。它的基域可以是Fp祖秒,也可以是F2m。F2m中的元素可以以多項(xiàng)式形式或正規(guī)基形式來表示舟奠。若用多項(xiàng)式形式竭缝,ANSI X9.62要求模多項(xiàng)式為不可約三項(xiàng)式,標(biāo)準(zhǔn)中提供了一些不可約三項(xiàng)式沼瘫,另外還給出了一個(gè)不可約五項(xiàng)式抬纸。為了提高通用性,針對(duì)每一個(gè)域提供了一個(gè)模多項(xiàng)式耿戚。若使用正規(guī)基表示方法湿故,ANSI X9.62規(guī)定使用高斯正規(guī)基。橢圓曲線最主要的安全因素是n膜蛔,即基點(diǎn)階坛猪,ANSI X9.62的n大于2160。橢圓曲線是使用隨機(jī)方法選取的皂股。ANSI X9.62規(guī)定使用以字節(jié)為單位的字符串形式來表示曲線上的點(diǎn)墅茉,ASN.1語法可以清楚地描述域參數(shù),公鑰和簽名呜呐。
2.FIPS 186-2
1997年就斤,NIST開始制定包括橢圓曲線和RSA簽名算法的FIPS 186標(biāo)準(zhǔn)。1998年蘑辑,NIST推出了FIPS186洋机,它包括RSA與DSA數(shù)字簽名方案,這個(gè)方案也稱為FIPS 186-1以躯。1999年NIST又面向美國G0vment推出了15種橢圓曲線槐秧。這些曲線都遵循ANSI X9.62和IEEE 1363-2000的形式。2000年忧设,包含ANSI X9.62中說明的ECDSA,使用上述曲線的FIPS 186-2問世颠通。
3址晕、IEEE 1363-2000
該標(biāo)準(zhǔn)于2000年作為IEEE標(biāo)準(zhǔn)問世。IEEE 1363的覆蓋面很廣顿锰,包括公鑰加密谨垃,密鑰協(xié)商启搂,基于IFP、DLP刘陶、ECDLP的數(shù)字簽名胳赌。它與ANSI X9.62和FIPS 186完全不同,它沒有最低安全性限制(比如不再對(duì)基點(diǎn)階進(jìn)行限制)匙隔,用戶可以有充分的自由疑苫。
因此IEEE 1363-2000并不是一個(gè)安全標(biāo)準(zhǔn),也不具有良好的通用性纷责,它的意義在于給各種應(yīng)用提供參照捍掺。它的基域可以是,也可以是再膳。 中的元素可以以多項(xiàng)式形式或正規(guī)基形式來表示挺勿。中元素表示形式是整數(shù),中元素表示形式是字符串喂柒。這與ANSI X9. 62和FIPS 186是一致的不瓶。
4.ISO/IEC 14888-3
這個(gè)標(biāo)準(zhǔn)包含若干簽名算法,其中ECDSA部分與ANSI X9.62一致灾杰。
如果大家有興趣可以研究下蚊丐,ECDSA算法在比特幣中用法。