什么是盲签?如何用RSA实现盲签?
阿牛哥 Lv4

什么是盲签?

盲签是一类特殊的签名方式。在一般的数字签名场合,签名者在文件或数据末尾附上自己的签名,表示该文件或数据确实是自己发出的。在这里,数据和签名是两部分,它们都由同一个人发出。

签名

而在另一些场合下,数据和签名可能由不同的人分别提供。也就是说,数据提供者负责提供数据,签名者负责签名。假如提供者在需要的到签名者的签名(背书)的同时,又不希望后者知道数据的具体内容,就需要应用盲签。

所谓盲签(Blind Signature),是一种在签名者不知道提供者所提供消息的内容的情况下,对消息进行签名的方式。

盲签流程示意图

盲签流程示意图

一些应用

一个现实世界的例子——投票

选民将填好的选票放入信封,信封上有选民的身份凭证,信封内除选票外还衬有一张复写纸。

当鉴定选民资格的官员收到信封后,根据信封上的凭证完成身份验证,官员在合格信封上签名。因为信封内有复写纸,签名同时被签到了选票上。而官员无法看到选票内容的。

选民收到签名后的信封,将选票取出并寄给负责计票的机构。

这个例子来自BitcoinWiki,是盲签在现实世界的恰当类比。装入信封相当于“盲化”,签名官员不知道选票内容,而从信封中取出签好名的选票则是“去盲化”。

央行数字货币

出于监管需要,央行发行的数字货币显然要具备一定的追踪(监管)能力,但在同时也需要具备一定的匿名性,不能过度跟踪给用户造成隐私方面的担忧。

央行要发行100元的数字货币,这些币要证明自己是真币,必须得到央行的背书,方法就是在每一张币中附带央行的签名。但光有签名还不够,因为这会导致所有100元的币都一个样,粘贴复制一下100就变200了,这显然是不行的。

所以,和纸币一样,为了防止复制,每张币都要包含一个唯一的编号。央行知道所有币的编号以及去向,但这样做的后果就是失去了隐私性。

那么,有没有办法既让央行能处理转账交易,却又不让它知道币的编号呢?

采用盲签方案是可以实现的。我们假设甲和乙要进行交易,交易分两个过程,一是甲从银行取钱,二是甲转账给乙,乙存入银行。

甲取钱的过程:

  1. 甲在本地产生币的编号
  2. 甲加密编号后,将加密后的编号告诉银行,请求银行给他100元的币
  3. 银行对甲的加密编号签名(背书),加收到后解密得到非加密编号的签名,此时甲拿到的就是100元真币了
  4. 甲在银行的账户余额被扣除100元

可见,此时币的编号不是银行生成的,而是甲自己生成的。

当甲给以转账100元时

  1. 甲将币的编号和签名告诉乙
  2. 乙请求银行验证编号和签名的正确性
  3. 银行验证通过,给乙增加100元存款

在以上过程中,银行不知道甲的编号,也就不知道乙的这一笔钱来自甲。上述过程理解起来也不困难。

RSA盲签的实现原理

盲签并不需要引入特别的算法,非对称的公钥加密算法就可以实现盲签。

以RSA为例,假设签名者的私钥为 (d, n)(d, \ n) ,公钥为 (e, n)(e, \ n) 要签名的信息为 mm ,盲签过程如下:

  1. 选定随机数 rr
  2. 计算加密后的消息 m=mre mod nm' = mr^e \ mod \ n
  3. 签名者对 mm' 签名: s=(m)d mod ns' = (m')^d \ mod \ n
  4. 接收者收到签名后计算实际的签名 ssr1(m)dr1mredr1mdrr1md (mod n)s \equiv s'r^{-1} \equiv (m')^dr^{-1} \equiv mr^{ed}r^{-1} \equiv m^drr^{-1} \equiv m^d \ (mod \ n)

相当于签名者对 mm 进行了签名,而因为经过随机数 rr 处理,签名者是不知道 mm 的内容的。如果对RSA加密的数学原理不了解,请看这篇文章《RSA加密算法原理》