0x01 概述
盲簽名(Blind Signature) 是由Chaum,David提出的一種數(shù)字簽名方式蝙眶,其中消息的內(nèi)容在簽名之前對簽名者是不可見的(盲化)。經(jīng)過盲簽名得到的簽名值可以使用原始的非盲消息使用常規(guī)數(shù)字簽名驗證的方式進行公開驗證崩掘。盲簽名可以有效的保護隱私,其中簽名者和消息作者不同粥帚,在電子投票系統(tǒng)和數(shù)字現(xiàn)金系統(tǒng)中會被使用圣贸。
盲簽名常常被類比成下面的場景:Alice想讓Bob在自己的文件上簽名,但是不希望Bob看到文件內(nèi)容于宙,于是Alice在文件上方疊放了一張復寫紙浮驳,然后將文件和復寫紙放入信封密封起來交給Bob。Bob再拿到信封后驗證了Alice的身份后捞魁,直接在密封好的信封上簽字至会,這樣雖然Bob是對密封后的信封簽字,但是Alice拿到簽名后的信封后谱俭,拆開信封就可以拿到經(jīng)過Bob簽字的文件奉件。
0x02 RSA盲簽名方案
盲簽名是一種消息在簽名之前就被盲化處理的數(shù)字簽名方案,盲簽名可以使用很多公鑰加密方案來實現(xiàn)昆著。這里只介紹最簡單的一種實現(xiàn)县貌,基于RSA加密算法的盲簽名方案。假設消息的持有者Alice希望對消息使用盲簽名方案進行簽名凑懂,Bob是簽名私鑰的控制者煤痕,他們兩方應該執(zhí)行以下步驟:
- Alice選擇一個隨機數(shù)
作為盲化因子
- Alice對原始的消息進行計算,
并把計算后(盲化)的消息
發(fā)送給Bob
- Bob計算
并把計算后的簽名值
發(fā)送給Alice
- Alice計算
,
就是Bob對原始消息
的數(shù)字簽名
證明:
0x03 C語言實現(xiàn)
因為需要使用大數(shù)運算摆碉,可以使用你熟悉的任何語言實現(xiàn)祟敛,也可以用任意成熟的大數(shù)運算庫實現(xiàn)。這里我使用了mbedTLS的大數(shù)運算庫兆解。
//首先使用盲化銀子blind_factor對原始的消息m進行盲化,生成盲化消息blind_message
int blindsignature_hide_message(mbedtls_mpi* m, mbedtls_mpi* blind_factor, mbedtls_mpi* e, mbedtls_mpi* n, mbedtls_mpi* blind_message)
{
int ret;
mbedtls_mpi r;
mbedtls_mpi_init(&r);
// r = blind_factor ^ e mod n
if ((ret = mbedtls_mpi_exp_mod(&r, blind_factor, e, n, NULL) ) != 0)
{
printf("Hide message: mbedtls_mpi_mod_init failed ret=%8X\r\n", ret);
goto EXIT;
}
// m1 = m * r
if ((ret = mbedtls_mpi_mul_mpi(blind_message, m, &r)) != 0)
{
printf("Hide message: mbedtls_mpi_mul_mpi failed ret=%08X\r\n", ret);
goto EXIT;
}
// blind_message = m1 mod n
if ((ret = mbedtls_mpi_mod_mpi(blind_message, blind_message, n)) != 0)
{
printf("Hide message: mbedtls_mpi_mod_mpi failed ret=%08X\r\n", ret);
goto EXIT;
}
EXIT:
mbedtls_mpi_free(&r);
return 0;
}
//對盲化的消息進行盲簽名跑揉,過程同普通rsa簽名一樣
int blindsignature_sign(mbedtls_mpi* blind_message, mbedtls_mpi* d, mbedtls_mpi* n, mbedtls_mpi* s)
{
int ret;
mbedtls_mpi r;
//s = m ^d mod n
if ((ret = mbedtls_mpi_exp_mod(s, blind_message, d, n, NULL)) != 0)
{
printf("Blind signature: mbedtls_mpi_exp_mod failed ret=%08X\r\n", ret);
goto EXIT;
}
EXIT:
return 0;
}
//對簽名結(jié)果blind_signature锅睛,使用blind_factor去盲化,得到簽名值signature
int blindsignature_unblind_sign(mbedtls_mpi* blind_signature, mbedtls_mpi* blind_factor, mbedtls_mpi* n, mbedtls_mpi* signature)
{
int ret;
mbedtls_mpi inv_blind_factor;
mbedtls_mpi_init(&inv_blind_factor);
if ((ret = mbedtls_mpi_inv_mod(&inv_blind_factor, blind_factor, n)) != 0)
{
printf("Unblind signature: mbedtls_mpi_inv_mod failed ret=%08X\r\n", ret);
goto EXIT;
}
if ((ret = mbedtls_mpi_mul_mpi(signature, &inv_blind_factor, blind_signature)) != 0)
{
printf("Unblind signature: mbedtls_mpi_mul_mpi failed ret=%08X\r\n", ret);
goto EXIT;
}
if ((ret = mbedtls_mpi_mod_mpi(signature, signature, n)) != 0)
{
printf("Unblind signature: mbedtls_mpi_mod_mpi failed ret=%08X\r\n", ret);
goto EXIT;
}
EXIT:
mbedtls_mpi_free(&inv_blind_factor);
return 0;
}
0x04 總結(jié)
RSA盲簽名的代碼历谍、調(diào)用示例程序都已經(jīng)上傳现拒,可以直接檢出測試,沒有仔細測試驗證可能有各種問題望侈,如果遇到問題印蔬,可以給我提issues。
git clone https://github.com/youngbug/blindsignatures_rsa.git
https://youngbug.github.io/cryptography/2022/06/15/Blind-Signature.html