基于RSA的盲签名算法Java实现

目录

盲签名概念

盲签名(Blind Signature): Alice有个数据想让Bob签名,但是不想让Bob知道真实的数据,于是有了盲签名的概念。盲签名在很多地方都有许多应用,如电子投票等。

一个通俗的解释是:Alice想让Bob在一张信件上签名,但是不想让B看到信件上面写的字,于是Alice在信件上面放了一张复写纸然后将信件和复写纸放到了信封中交给Bob。Bob在拿到了信封之后直接在信封上面签字,这样字迹就通过复写纸写到了信件上面,Alice拿到了信封之后就可以得到Bob签字过的信件。

基于RSA的盲签名原理

前提:Bob的公开密钥 e ,私钥d,和一个公开模数 n ,Alice打算让Bob盲签。

Created with Raphaël 2.1.0AliceAliceBobBob选取随机值作为盲化因子,计算隐藏消息t对t进行签名解盲

(1)Alice选取盲因子k然后计算 m

t=mke(modn)

(2)Bob对 t 签名
td=(mke)d(modn)

(3)Alice通过计算揭开 td

s=td/k(modn)

(4)结果为:
s=md(modn)

证明:

td(mke)dmdk(modn)

td/k=mdk/kmd(modn)

这个证明过程是存在问题的,问题会在代码是现阶段暴露出来,后面会有朔宁。

Java实现

import java.math.BigInteger;
/**
 * 盲签名相关
 * Created by forest on 2017/5/23.
 */
public class blindSignature {
    public static void main(String[] args){
        System.out.println("这里是盲签名测试");

        BigInteger e = new BigInteger("32663");
        BigInteger d = new BigInteger("23");
        BigInteger n = new BigInteger("42167");

        BigInteger m = new BigInteger("123");       //签名的消息
        BigInteger factor = new BigInteger("37");   //盲因子

        BigInteger blindMsg = blindHideMsg(m, factor, e, n);
        BigInteger blindSig = blindSignature(blindMsg, d, n);
        BigInteger sig = blindRetriveSig(blindSig, factor, n);
        System.out.println("盲签名 = " + sig);
        BigInteger realSig = m.modPow(d, n);
        System.out.println("原签名 = " + realSig);
    }

    /**盲签名-盲化*/
    public static BigInteger blindHideMsg(BigInteger msg, BigInteger factor, BigInteger e, BigInteger n){
        BigInteger hideMsg = msg.multiply(factor.modPow(e, n)).mod(n);
        return hideMsg;
    }

    /**盲签名-签名*/
    public static BigInteger blindSignature(BigInteger blindMsg, BigInteger d, BigInteger n){
        BigInteger blindSig = blindMsg.modPow(d, n);
        return blindSig;
    }

    /**盲签名-解盲得到签名*/
    public static BigInteger blindRetriveSig(BigInteger blindSig, BigInteger factor, BigInteger n){
        BigInteger signature = blindSig.divide(factor);
        return signature;
    }
}

测试结果

这里是盲签名测试
盲签名 = 957
原签名 = 14633

我们可以看到这里的盲签名与原签名不一致,问题出在解盲的过程中不应该采用除法而应该采用乘法求逆元。正确代码如下:

/**盲签名-解盲得到签名*/
    public static BigInteger blindRetriveSig(BigInteger blindSig, BigInteger factor, BigInteger n){
        BigInteger signature = blindSig.multiply(factor.modInverse(n)).mod(n);
        return signature;
    }

结果为

这里是盲签名测试
盲签名 = 14633
原签名 = 14633

错误来源

td/k=mdk/kmd(modn)

正确的应该是
tdk1=mdkk1md(modn)

参考书目

《应用密码学-协议、算法与C源程序》第二版23.12节

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值