RSA簽名驗籤學習筆記

  RSA私鑰簽名時要基於某個HASH算法,好比MD5或者SHA1等。以前我一直認爲簽名的過程是:先對明文作HASH計算,而後用私鑰直接對HASH值加密。最近才發現不是那麼簡單,須要對HASH後的數據進行BER編碼再加密。算法

先看一個例子。數組

公鑰模:89 54 E6 61 C1 52 DB ED 07 57 50 04 AD B3 D2 A7 A9 8F E8 D8 20 5B 01 B2 E5 E4 7A 7B EE 80 E3 C0 13 11 D2 F9 AD C3 CC 5F 1D 96 AC B2 AB BE 9C 14 9E 76 31 06 B2 E6 FA 01 52 A7 2E 53 C2 1D 3B 7B 9B 68 05 D2 5E 35 31 98 0E 02 93 E0 D9 0C 38 2D 3D EE 10 E6 87 53 79 DF B2 1E 12 D9 9E EF 89 6D 01 59 0D 13 94 DB 05 B7 09 34 D3 5B AB ED 7C FE 0E BE 87 EE E8 DD 01 39 3A CA 3A A7 17 B8 AA E3編碼

公鑰指數:01 00 01加密

私鑰指數:01 FE B1 BA 09 CC E2 54 F7 1E 55 93 3B D2 B8 E4 A6 99 E8 8F FB 28 57 45 FA 00 EF A6 8D 38 62 16 90 30 5A 18 36 65 F9 BA 07 FC 00 56 38 18 74 BB F7 F1 4F 95 01 54 49 9D 6B 4D F2 66 55 13 87 A1 A6 95 74 72 6A D8 3A EA 34 A8 F8 40 5F 27 11 30 4F 96 3A 2E 7B E6 B6 47 3C 3B 4D 24 E8 FA 51 19 59 FB 52 E0 9B D2 24 B3 B5 8A 36 BF 34 20 E9 2A AB 5D 55 9B 60 01 D5 04 81 E8 E7 EC B2 5F 81 41spa

私鑰P:BF 36 08 66 63 74 6A 79 D0 77 64 21 73 6D 1A B9 13 BB 35 13 BE A6 73 84 C8 7D 83 67 BE C2 F5 0C 3A 7F 5F EF 6E 73 E2 BC 31 D2 0C 78 06 D7 38 85 7E F5 06 40 62 A6 1D 53 CC 97 34 30 58 EE E2 05對象

私鑰Q:B7 DD 46 99 58 B2 52 4B 87 FB E1 F1 09 44 AB 9A AD D1 93 90 9C 40 E0 2F 36 63 F4 7F 49 CB 36 E3 2C DA 85 5C 6E CE 41 AC CB 09 6C 27 B6 44 2B D8 26 5F D5 63 DF 2A C8 60 57 3B 23 13 2B 5F 65 C7接口

私鑰DP:A6 EF C4 9B A7 9E DE CA E5 2F 27 33 71 33 C3 0D EC 65 18 2C D9 D9 36 A7 A9 E6 B2 CF E3 A3 10 10 12 0E 5C B2 8C 2B 0E BC 21 7E F2 35 E4 3B 08 74 BC 67 AD 82 8E DD DA 62 EC 0E E2 98 87 3C 60 05md5

私鑰DQ:B6 A0 8B A7 75 7A 6A 53 AB D6 7D 2E 35 CE 87 C5 34 31 9F 29 5C 8A F4 22 F1 1B 87 97 87 6C DA 2F FC 35 71 91 C6 5E 08 CD E1 3E 92 B7 3F 4B A7 61 23 7C BD 30 5E 52 D8 85 19 20 1C 4E C6 1E 13 B1ci

私鑰InvQ:B4 12 D6 05 1C 2C 2B 6F B5 73 99 F3 B7 A7 08 6F A3 E8 2D 6F 33 A6 AE E5 BE 7B 89 86 7F 48 3B DD BC 4A 07 BF A4 A1 BB 96 BD 0E 46 F1 43 FA FB DE A0 1B AB 38 7D 49 59 45 EE 8C F9 3D 89 CF EB AC字符串

明文:11 22 33 44 55

經過調用.NET的RSA簽名接口,產生基於MD5的簽名後數據:56 E1 5E 29 84 D6 BC FB 87 7F 55 93 B4 E1 F3 75 2C 64 A5 BC 04 3A D7 0A DB 84 AD 8B 9C 4D D8 E6 8A 56 85 7B 2C 5E 50 E5 81 EB DC 40 D8 9A 29 64 54 19 5B F0 2B 77 D3 DB CF A2 17 BF 33 3F 19 19 B0 FF 36 53 D3 C2 36 1D 90 43 27 2C 0F 54 34 54 F7 E8 D2 09 75 E4 F1 A0 8B F5 38 EA 66 D6 53 14 E4 C5 B6 5A C7 74 52 6E 0A 16 C6 9B B7 81 0B 06 61 8A E7 41 BB 97 E6 EE 3E 6A 1C 7A E6 32 18 60

用公鑰對上面的數據解密後獲得:30 20 30 0C 06 08 2A 86 48 86 F7 0D 02 05 05 00 04 10 28 3D 4F EA 5D DE D5 9C F8 37 D3 04 73 28 F5 AF

這是一段TLV格式的數據,解析後

TAG

名稱

長度

30

Sequence組合類型

20

 
 

30

Sequence組合類型

0C

 
   

06

對象標識ObjectID

08

2A 86 48 86 F7 0D 02 05

   

05

空類型

00

 
 

04

字符串類型

10

28 3D 4F EA 5D DE D5 9C F8 37 D3 04 73 28 F5 AF

能夠看到28 3D 4F EA 5D DE D5 9C F8 37 D3 04 73 28 F5 AF正好就是明文數據11 22 33 44 55的MD5值。

那麼上面這段數據的其它內容表示什麼意思呢?

這裏使用的編碼方法是BER(Basic Encoding Rule),BER的數據都是TLV格式的,每種TAG的定義以下:

0x01:BOOL

0x02:INT,整型

0x04:OCTSTR,字符串類型

0x05:NULL,空類型

0x06:OBJID,對象標識ObjectID(在這裏就是對應的HASH算法的OID編碼)

0x0A:ENUM

0x30:SEQ,Sequence組合類型

0x31:SETOF

0x40:IPADDR

0x41:COUNTER

0x42:GAUGE

0x43:TIMETICKS

0x44:OPAQUE

也就是說,每次基於不一樣的HASH算法對不一樣的數據進行簽名時,構造的這一段BER數據的基本格式是固定不變的,只是HASH算法的OID和哈希值會變而已。

       下面講一下HASH算法的OID是怎麼編碼的。

       每一個算法的OID都是固定的一串十進制數據,是國際權威組織定的。好比MD5的OID 是 1.2.840.113549.2.5   ,表示爲"iso(1) member-body (2) US (840) rsadsi(113549) digestAlgorithm (2) md5 (5)", 因此當解碼程序看到這個OID時,就知道是MD5散列.

       對OID的編碼規則以下:前兩部分若是定義爲x.y, 那麼它們將合成一個字40*x + y, 其他部分單獨做爲一個字節進行編碼。每一個字首先被分割爲最少數量的沒有頭零數字的7位數字.這些數字以big-endian格式進行組織,而且一個接一個地組合成字節. 除了編碼的最後一個字節外,其餘全部字節的最高位(位8)都爲1。舉例: 30331 = 1 * 128^2 + 108 * 128 + 123   分割成7位數字(0x80)後爲{1,108,123}設置最高位後變成{129,236,123}.若是該字只有一個7位數字,那麼最高爲0。

規則不太好懂,仍是以MD5舉例

1、將1.2.840.113549.2.5轉換成字數組 {42, 840, 113549, 2, 5}(由於前兩部分定義爲1.2,那麼合成一個字40*1+2=42)

2、將每一個字分割爲帶有最高位的7位數字。

42=42,只有一個7位數字,那麼最高爲0,結果爲{0x2A}

840= 6*128^1+72,除最後一個字節外,其餘字節的BIT8都置1,結果爲{0x86,0x48}

113549=6*128^2+119*128^1+13,除最後一個字節外,其餘字節的BIT8都置1,結果爲{0x86,0xF7,0x0D}

2=2, 只有一個7位數字,那麼最高爲0,結果爲{0x02}

5=5, 只有一個7位數字,那麼最高爲0,結果爲{0x05}

最終結果爲{{0x2A},{0x86,0x48},{0x86,0xF7,0x0D},{0x02},{0x05}}

3、加上TAG和LEN,獲得OID編碼爲 0x06 08 2A 86 48 86 F7 0D 02 05

 

RSA驗籤時的步驟:先用公鑰解密,解析TLV數據從中獲得HASH算法的OID和HASH值,根據OID選擇相應的HASH算法對明文進行計算,最後比對HASH值。

 

常見的HASH算法在用於RSA簽名時的BER數據編碼格式爲:

MD2

1.2.840.113549.2.2

30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04 10 || H.

MD4

1.2.840.113549.2.4

30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 04 05 00 04 10 || H.

MD5

1.2.840.113549.2.5

30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04 10 || H

SHA1

1.3.14.3.2.26

30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H

SHA224

2.16.840.1.101.3.4.2.4

不肯定是否這個OID

30 2D 30 0d 06 09 60 86 48 01 65 03 04 02 04 05 00 04 1C || H

SHA256

2.16.840.1.101.3.4.2.1

30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 || H

SHA384

2.16.840.1.101.3.4.2.2

30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00 04 30 || H

SHA512

2.16.840.1.101.3.4.2.3

30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40 || H

SM3

1.2.156.197.1.504

不肯定是否這個OID

30 30 30 0c 06 08 2a 81 1C 81 45 01 83 78 05 00 04 20 || H.

相關文章
相關標籤/搜索