※ 引述《yoco315 (眠月)》之铭言:
: 想要了解一下,有没有可能作到一种网络投票系统,
: 同时具有“验证身份合法性”的功能,以及“不具名投票”的特性?
: 1. 只有合法的身份(透过自然人凭证或类似的)可以送出合法的封包
: 不合法的身份产生的封包在服务器会被挡下来
: 2. 一个身份只能送出一次合法的封包
: 第二次以后就会被服务器挡掉
: 3. 系统无法从单一投票封包看出该选民的选项是谁(以确保不具名投票的特性)
: 但可以根据所有的投票封包统计出每一位候选人的得票数是多少
: 前两个不难想像,但第三点我一直很卡 XD
: 感觉就是数学或是密码学问题,有没有人对这方面有研究的?
: 想要了解一下未来的人类社会是不是有机会能透过科技降低“直接民主”的门槛
: 不知道这样的系统有没有可能实现,防弊的能力如何…
这是有趣的问题
推文太长 打一堆不如回一篇好了 我没读过相关的论文
但知道盲签章好像其中一个用途就是在做投票用的
所以就想如果是我来做会怎样做 只是个大略的想法
我喜欢自己先想出方法来再看别人怎么做
首先,这个方法用到盲签
http://en.wikipedia.org/wiki/Blind_signature
它是基于 RSA 超长质数的算法变形,盲签目前安不安全我不太清楚
假设它安全好了,或是有其它替代的安全方法
简单的语言来解释盲签的话,就是 我把我写的信和复写纸装在信封里封好
交给某个人签章,某人拿到这信封看不到里面,但他可以在信封外签名
签好后拿回来,拆开,就得到了某个人签章,但某人却无法得知内容
以电脑处理的算法大约会是这样
encrypted_text = encrypt(plain_text, public_key)
signed_encrypted_text = ca_blind_sign(encrypted_text)
signed_text = decrypt(signed_encrypted_text, private_key)
接着进入方法正题,定义几个角色
投票者 - 一般投票的人
CA - 公证单位
计票者 - 负责计票的单位
1. 制造选票
首先,投票者造一张票
vote = (nonce, choose)
里头包含两样资讯
nonce - 一串够长的随机乱数
choose - 投票的选择
这两样资讯不包含任何个人讯息,所以无法推回是谁投的票
为了不让 CA 知道我投了谁,所以在送出前我先用自己的公钥
(不太确定实作细节,但我想应该是)
进行盲签加密
encrypted_vote = encrypt((nonce, choose), public_key)
2. 交由 CA 进行盲签章
有了加密后的票,传给 CA ,CA 在接受前要检查自然人凭证
确认投票人的资格,及是否有重复,没问题的话,CA 会签章
signed_encrypted_vote = sign(encrypt((nonce, choose), public_key))
签完后传回给投票人
3. 投票人解密
投票人拿回来后解密
signed_vote = sign((nonce, choose))
成为一张有效票
4. 投票人经由 P2P 或暱名网络传给 计票者
投票人不直接传给计票者,是因为这样一做,可能就会因为连线的资讯
曝露了自己的身份,取而代之的方法,是透过 P2P 网络
像是 Tor ,或是专门设计的 P2P 网络,使用 P2P 网络还有个好处
计票者如果要恶搞很简单,票明明有一千张,但我说我只看见五百张
可是如果是公开的 P2P 网络,大家票互相乱传,这都是公开的
每个人都可以当计票者,或著说投票者也是计票者的一员
这除了有暱名的作用,还有顺便监票的作用,有效票传到每人手上
因为上面的签章每人都可以验
计票过程中,同样 nonce 只会被算一次,如果出现两张票以上
有着同样的 nonce ,就全都视为废票
接着来看这系统是怎样满足需求
1. 合法的身份才能投
这点自然人凭证之类的 PKI 系统做掉了,我们假设他们是安全的
(当然,可能还是有弱点,但谈理论一般都只假设用的某项手法是安全的
实作的细节问题就暂不管他),所以这点问题不大
2. 同样的人只能投一次 (或系统设定的次数)
在 CA 那边的数据库可以存这些,所以同一人第二次要求 CA 做盲签时就会被拒决
3. 暱名性
票本身是不俱名的,传送的手法也尽量保持暱名,所以是非常难以得知投票人是谁
你拿到一张票可能长这样
ABD897FgljdF9aJL2Amqfo, "候选人 1 号"
前面是 nonce ,也就是无意义的乱数,后面是选择,这些都无从推起投票人是谁
唯注意签章不能带有 timestamp ,否则 CA 可透过来盲签的时间得知到底是谁投的
接着谈谈攻击手法的各种可能性
1. nonce 碰撞攻击
想让你的票变废票,就是开出一张跟你一样 nonce 的票,但只要这是够长的乱数
乱数产生器的品质够好,你猜不到就没办法撞到我的 nonce,在这样假设前提下
nonce 碰撞攻击是无效的,除此之外,就算让你猜得到好了,要让我的票变废票
你自己的票也会变废票,也没太大好处,不如去投对自己有利的人
另一种可能出现的情况是大家约好开同样的 nonce 去投票,例如
"我爱大咪咪", "候选人 1 号"
"我爱大咪咪", "候选人 2 号"
"我爱大咪咪", "候选人 3 号"
像这样也只是来搞笑投废票的,他不投票或要投废票都是一样的,对选情没影响
2. 有效票的复制
有效票在这系统里本来就是设计给 P2P 节点到处乱传的
在每张票都有一个独一无二的 nonce 的情况下
除非出现
"同样 nonce", "候选人 1 号"
"同样 nonce", "候选人 2 号"
同 nonce 不同选择,才会被当废票,在这种情况下 replay 攻击应该起不了做用
除此之外,有效票有 CA 的签章保护,除非能破解,但那又是另外的议题了
在这假设盲签章是安全的
3. P2P 网络的筛选
透过渗透 P2P 网络确实是一个有可能的方法,但是要花的成本太高
只要参与的节点够多,就很难被破解,你可以安插你自己的节点
遇到你的对手的选票全都丢掉,但你无法阻止正常的节点散播选票
如果这 P2P 网络加上奖励机制的话,让帮忙散播的正常节点有好处拿
攻击者要竞争就更难了,只是详细细节还得想怎样做,但大致方向是这样
4. CA 攻击
整个系统看下来我想最大的弱点在 CA ,在这里必须假设 CA 是公正无私
且不会被攻破的,否则,CA 能干的坏事太多了,权力和信认太集中
其实都不是太好的设计,CA 要是想多给某人几张票,这都没法挡
所以我想要改进的话,最好是能拿掉 CA 这样的角色,变成完全分布式的设计
不过这样做又有个矛盾,在于投票可能无可避免需要有民众的资料
要如何做到去中心化要能够验证民众的身份 可能会非常困难
以上,只是一个很直观的做法,可能还有我没考虑到的问题和安全问题
欢迎提出来讨论,如果有空的话蛮想实做这样的专案来玩玩
非常有趣的题目