密碼之ECDSA數(shù)字簽名算法

轉(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ù)問(wèn)題(discrete logarithm problem DLP)和大數(shù)分解問(wèn)題(integer factorization problem IFP)不同,橢圓曲線離散對(duì)數(shù)問(wèn)題(elliptic curve discrete logarithm problem ECDLP)沒(méi)有亞指數(shù)時(shí)間的解決方法。因此橢圓曲線密碼的單位比特強(qiáng)度要高于其他公鑰體制。

數(shù)字簽名算法(DSA)在聯(lián)邦信息處理標(biāo)準(zhǔn)FIPS中有詳細(xì)論述,稱為數(shù)字簽名標(biāo)準(zhǔn)。它的安全性基于素域上的離散對(duì)數(shù)問(wèn)題。橢圓曲線密碼(ECC)由Neal Koblitz和Victor Miller于1985年發(fā)明。它可以看作是橢圓曲線對(duì)先前基于離散對(duì)數(shù)問(wèn)題(DLP)的密碼系統(tǒng)的模擬,只是群元素由素域中的元素?cái)?shù)換為有限域上的橢圓曲線上的點(diǎn)。

橢圓曲線密碼體制的安全性基于橢圓曲線離散對(duì)數(shù)問(wèn)題(ECDLP)的難解性。橢圓曲線離散對(duì)數(shù)問(wèn)題遠(yuǎn)難于離散對(duì)數(shù)問(wèn)題,橢圓曲線密碼系統(tǒng)的單位比特強(qiáng)度要遠(yuǎn)高于傳統(tǒng)的離散對(duì)數(shù)系統(tǒng)。因此在使用較短的密鑰的情況下,ECC可以達(dá)到于DL系統(tǒng)相同的安全級(jí)別。這帶來(lái)的好處就是計(jì)算參數(shù)更小,密鑰更短,運(yùn)算速度更快,簽名也更加短小。因此橢圓曲線密碼尤其適用于處理能力、存儲(chǔ)空間、帶寬及功耗受限的場(chǎng)合。

二、ECDSA原理

ECDSA是ECC與DSA的結(jié)合,整個(gè)簽名過(guò)程與DSA類似,所不一樣的是簽名中采取的算法為ECC,最后簽名出來(lái)的值也是分為r,s。

簽名過(guò)程如下:

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)證過(guò)程如下:

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、如果等式成立,接受簽名,否則簽名無(wú)效。

三、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ì)的方式:與算法無(wú)關(guān)的方式和特定于算法的方式。

下面我們將按照指定ECDSA算法去生成秘鑰KeyPairGenerator.getInstance("EC");

2、ECDSAPublicKey

ECDSA公用密鑰的接口

3、ECDSAPublicKey

ECDSA 專用密鑰的接口

4、PKCS8EncodedKeySpec

PKCS8EncodedKeySpec類繼承EncodedKeySpec類,以編碼格式來(lái)表示私鑰。

PKCS8EncodedKeySpec類使用PKCS#8標(biāo)準(zhǔn)作為密鑰規(guī)范管理的編碼格式

5、Signature

Signature 類用來(lái)為應(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)過(guò)頒發(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ī)基形式來(lái)表示。若用多項(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é)為單位的字符串形式來(lái)表示曲線上的點(diǎn),ASN.1語(yǔ)法可以清楚地描述域參數(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又面向美國(guó)G0vment推出了15種橢圓曲線。這些曲線都遵循ANSI X9.62和IEEE 1363-2000的形式。2000年,包含ANSI X9.62中說(shuō)明的ECDSA,使用上述曲線的FIPS 186-2問(wèn)世。

3、IEEE 1363-2000

該標(biāo)準(zhǔn)于2000年作為IEEE標(biāo)準(zhǔn)問(wèn)世。IEEE 1363的覆蓋面很廣,包括公鑰加密,密鑰協(xié)商,基于IFP、DLP、ECDLP的數(shù)字簽名。它與ANSI X9.62和FIPS 186完全不同,它沒(méi)有最低安全性限制(比如不再對(duì)基點(diǎn)階進(jìn)行限制),用戶可以有充分的自由。

因此IEEE 1363-2000并不是一個(gè)安全標(biāo)準(zhǔn),也不具有良好的通用性,它的意義在于給各種應(yīng)用提供參照。它的基域可以是,也可以是。 中的元素可以以多項(xiàng)式形式或正規(guī)基形式來(lái)表示。中元素表示形式是整數(shù),中元素表示形式是字符串。這與ANSI X9. 62和FIPS 186是一致的。

4.ISO/IEC 14888-3

這個(gè)標(biāo)準(zhǔn)包含若干簽名算法,其中ECDSA部分與ANSI X9.62一致。

如果大家有興趣可以研究下,ECDSA算法在比特幣中用法。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容