Java中的确定性RSA加密

Java中的确定性RSA加密,java,encryption,rsa,encryption-asymmetric,deterministic,Java,Encryption,Rsa,Encryption Asymmetric,Deterministic,这是我在这个网站上的第一个问题,我对RSA只有基本的数学理解,所以请耐心听我说!) 我正在为大学最后一年的项目编写一个Java web应用程序。这是一个基于网络的“Pret-a-voter”的实现,这是一个安全的投票系统,面向那些听说过它的人 本质上,我的问题是,我希望能够让某人担任审计员: 源字节数组(要加密的明文) RSA公钥文件 一个“目标”字节数组,它是我自己在给定明文和公钥的情况下计算密码数据的结果 然后我希望审核员能够使用前两项执行加密,并确信第三项是结果。因此,我需要加密是确定

这是我在这个网站上的第一个问题,我对RSA只有基本的数学理解,所以请耐心听我说!)

我正在为大学最后一年的项目编写一个Java web应用程序。这是一个基于网络的“Pret-a-voter”的实现,这是一个安全的投票系统,面向那些听说过它的人

本质上,我的问题是,我希望能够让某人担任审计员:

  • 源字节数组(要加密的明文)
  • RSA公钥文件
  • 一个“目标”字节数组,它是我自己在给定明文和公钥的情况下计算密码数据的结果
然后我希望审核员能够使用前两项执行加密,并确信第三项是结果。因此,我需要加密是确定性的,即每次重复使用相同的明文和公钥加密时生成相同的密码数据

(注意-我在这个项目中使用的是非常小的数据块-根本不涉及对称加密…我知道这是RSA的一个“有趣”的用法!)

无论如何,我在Java中发现了这一点,使用

cipher = Cipher.getInstance("RSA");
使用默认的随机填充方案,代价是11字节(因此使用2048位密钥对,可以加密2048/8-11=245字节)。重复加密相同的明文会产生不同的密文,这显然不是我想要的ECB模式

我的问题是-我应该使用以下选项吗?

cipher = Cipher.getInstance("RSA/ECB/NoPadding");
我在很多地方都读到,没有填充,RSA是不安全的。这仅仅是因为攻击者可以构建明文/密文字典吗?这是确定性加密的一个副作用,我需要确定性加密,以允许审计员验证我的加密,在我的方案中,审计员是可信的,所以这是可以的

我问题的第二部分与java更相关。如果我像上面那样使用RSA/ECB/NoPadding,我相信我能够提供长度为128的源字节数组(对于1024位RSA密钥对),并对其进行加密以获得另一个长度为128的字节数组。如果我再次尝试用不同的1024长度公钥加密,我会得到

javax.crypto.BadPaddingException:消息大于模数

有人知道为什么吗

编辑-使用NoPadding进行加密并不总是生成此异常-这是喜怒无常的。但是,即使加密未生成此异常,解密也会生成此异常:

javax.crypto.BadPaddingException:数据必须以零开头

非常感谢您通读这篇文章!任何帮助都将不胜感激

编辑-抱歉,我最初的问题不是很清楚我想做什么,所以这里有一个[尝试]解释:

  • 明文是选民在选举中的投票
  • Pret-a-voter的目标是在不牺牲选民保密性(etc)的情况下实现端到端的可验证性。投票后,选民会收到一张收据,他们可以用它来验证他们的投票记录是否正确,并在稍后向他们显示他们的投票没有被篡改。投票人将其收据上的信息与网上发布的相同副本进行比较
  • 但是,任何选民都不可能证明他/她是如何投票的(因为这可能导致胁迫),因此信息不是明文,而是投票的加密副本
  • 事实上,明文被加密四次,使用四个不同的非对称密钥——由两个不同的出纳员持有,每个出纳员持有两个密钥。因此,一个投票(明文)被提供给一个出纳员,出纳员使用公钥#1对其进行加密,然后用他的第二个公钥对该密文进行加密,然后将该密文交给第二个出纳员,第二个出纳员用他的两个密钥以同样的方式对其进行加密。由此产生的密文(四次顺序加密的结果)是发布到web(公开)的内容。出纳员是值得信任的
  • 每一张加密的选票都可以被视为一个“洋葱”,中心是选票,有几个加密层。为了投票,每一层都必须依次移除,这意味着相应的私钥(由出纳员持有)必须按相反的顺序应用。这是安全的关键——所有出纳员必须协同工作才能解密投票
  • 网络公告栏可以可视化为一个有5列的表格-第一列(左侧)保存完全加密的选票(也显示在每个选民的收据上),并且是投票阶段唯一可见的列。第二列包含相同的投票集,但外层已移除-出纳员2通过在计票阶段使用其私钥解密投票来填充此列和第3列。在计票阶段结束时,第5列包含可以进行计票的完全解密的选票
  • 每个投票人都会收到一张收据,将他们链接到第1列中的加密投票。这不会显示他们是如何投票的,但允许他们验证他们的投票没有被篡改,因为在整个选举过程中,他们可以验证他们的加密投票仍然在第1列,未被篡改。当然,这只是“端到端验证”的一半,因为选民无法验证解密是否正确,即第2列中有一个条目,即他们的投票减去加密的外层。每个投票人仅负责第1列之前的验证
  • 此后,审计员有责任检查第1列中的条目是否解密到第2列,依此类推。他们这样做的方式是依靠确定性加密,并且用于加密的公钥是公开的
  • 由于公钥是公共的,所以您不希望人们简单地从第5列到第1列划出一条线,将某人的投票连接起来