0x01 概述
盲签名(Blind Signature) 是由Chaum,David提出的一种数字签名形式,其中音讯的内容在签名之前对签名者是不可见的(盲化)。通过盲签名失去的签名值能够应用原始的非盲音讯应用惯例数字签名验证的形式进行公开验证。盲签名能够无效的爱护隐衷,其中签名者和音讯作者不同,在电子投票系统和数字现金零碎中会被应用。
盲签名经常被类比成上面的场景:Alice想让Bob在本人的文件上签名,然而不心愿Bob看到文件内容,于是Alice在文件上方叠放了一张复写纸,而后将文件和复写纸放入信封密封起来交给Bob。Bob再拿到信封后验证了Alice的身份后,间接在密封好的信封上签字,这样尽管Bob是对密封后的信封签字,然而Alice拿到签名后的信封后,拆开信封就能够拿到通过Bob签字的文件。
0x02 RSA盲签名计划
盲签名是一种音讯在签名之前就被盲化解决的数字签名计划,盲签名能够应用很多公钥加密计划来实现。这里只介绍最简略的一种实现,基于RSA加密算法的盲签名计划。假如音讯的持有者Alice心愿对音讯$m$应用盲签名计划进行签名,Bob是签名私钥的控制者,他们两方应该执行以下步骤:
- Alice抉择一个随机数$k$作为盲化因子
- Alice对原始的音讯进行计算,$m' = m k^e (mod \ n)$ 并把计算后(盲化)的音讯 $m'$发送给Bob
- Bob计算 $s' = (m')^d (mod \ n)$ 并把计算后的签名值 $s'$ 发送给Alice
- Alice计算 $s = s'k^{-1} (mod \ n)$,$s$ 就是Bob对原始音讯 $m$的数字签名
证实:
$(m')^d \equiv (m k^e)^d \equiv m^d k \ (mod \ n) $
$(m')^d k^{-1} = (m k^e)^d k^{-1} = m^d k^{e d} k^{-1} = m^d k k^{-1} \equiv m^d$
0x03 C语言实现
因为须要应用大数运算,能够应用你相熟的任何语言实现,也能够用任意成熟的大数运算库实现。这里我应用了mbedTLS的大数运算库。
//首先应用盲化银子blind_factor对原始的音讯m进行盲化,生成盲化音讯blind_messageint 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;}//对签名后果blind_signature,应用blind_factor去盲化,失去签名值signatureint 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 总结
RSA盲签名的代码、调用示例程序都曾经上传,能够间接检出测试,没有认真测试验证可能有各种问题,如果遇到问题,能够给我提issues。
git clone https://github.com/youngbug/blindsignatures_rsa.git