共计 2711 个字符,预计需要花费 7 分钟才能阅读完成。
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_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;
}
// 对签名后果 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 总结
RSA 盲签名的代码、调用示例程序都曾经上传,能够间接检出测试,没有认真测试验证可能有各种问题,如果遇到问题,能够给我提 issues。
git clone https://github.com/youngbug/blindsignatures_rsa.git