java - 编码 RSA 算法 Java
问题描述
所以,我试图从头开始创建一个 RSA 算法。
到目前为止,我已经成功创建了选择两个素数的能力(在我当前的示例中,我有 11 和 13。然后,我通过执行 px q 计算 N。得到 143。
然后,我继续使用我的 public BigInteger findZ()
方法来计算 φ,即 (p-1)(q-1)。
使用这个新计算的 φ,我想找到一个数字,或者更确切地说创建一个遵循 1<(e)<φ 或简单 gcd(e,φ) = 1 的 e 变量因此,我最初将 temp 设置为等于我的常数 ONE (等于一)+ 1 来满足范围。但是,经过不断的调试尝试,循环永远不会找到 GCD 等于 1 的值,因为我需要使用 BigInteger,所以我创建了一个常量来表示。是否有一个原因?
这是我的代码。
import java.math.BigInteger;
public class RSA
{
//Intialize the variables.
private BigInteger p;
private BigInteger q;
private BigInteger n;
private BigInteger z;
final private BigInteger ONE = BigInteger.valueOf(1);
public BigInteger getP()
{
return p;
}
public BigInteger getQ()
{
return q;
}
//Computes N, which is just p*q.
public BigInteger findN()
{
n = p.multiply(q);
return p.multiply(q);
}
public BigInteger findZ()
{
long pMinusOne = p.intValue() - 1;
long qMinusOne = q.intValue() - 1;
z = BigInteger.valueOf(pMinusOne * qMinusOne);
return z;
}
public BigInteger getE()
{
int temp = ONE.intValue() + 1;
BigInteger GCD = BigInteger.valueOf(temp);
while (GCD.gcd(z).compareTo(ONE) != 0)
{
temp++;
}
e = BigInteger.valueOf(temp);
return e;
}
}
任何帮助是极大的赞赏。
谢谢!
解决方案
既然您要求任何帮助,我将回答您的问题并提供其他提示。
如何获得电子
一个提示是使用equals()
而不是compareTo()
仅在检查相等性时使用。有时这可以减少正在完成的工作量,并且也更容易阅读。
您的代码中最大的错误temp
是用于设置 的原始值GCD
,但未链接temp
到 GCD。他们保持断开连接。如果您temp
以后更改,GCD
将不知道并且不会更改。您需要GCD
直接添加一个。这是一些示例代码:
BigInteger e = BigInteger.valueOf(3);
while (! phi.gcd(e).equals(BigInteger.ONE)) {
e = e.add(BigInteger.ONE);
}
查看 overBigInteger
的方法
BigInteger
通过使用您最喜欢的搜索引擎并进行搜索,了解您可以轻松使用 's 做什么BigInteger 8 API
。8 适用于您正在使用的 Java 版本,因此可能会发生变化。API 用于方法列表。
在搜索结果的早期,您应该找到这个 API 页面。BigInteger
有很多好用又方便的方法,快来看看吧。它甚至有一个构造函数,可以为您提供BigInteger
您想要的任何大小,这很可能是一个素数,这对于为新的随机 RSA 密钥生成素数非常有用。
使用BigInteger
的内置常量
不要重新创建以下常量(显示在上面的 API 页面中):
BigInteger.ZERO
BigInteger.ONE
BigInteger.TEN
除非您确定它适合,否则切勿转换BigInteger
为long
您正在将BigInteger
s 转换为long
,这是一个坏主意,因为有很多BigInteger
s 不适合 a long
,从而给您不正确的结果。为了正确性(这比速度更重要),直接用s做算术BigInteger
。
当您intValue()
获得long
. 使用longValueExact()
. 就此而言,intValueExact()
请在获得int
.
因此,要计算 φ:
BigInteger pMinusOne = p.subtract(BigInteger.ONE);
BigInteger qMinusOne = q.subtract(BigInteger.ONE);
BigInteger phi = pMinusOne.multiply(qMinusOne);
现在您知道它会给出正确的结果,即使对于更大BigInteger
的 s。它也不难阅读,这有利于以后维护代码。
存储什么
您还应该只存储n和e(以及d,但前提是它是私钥)永远不要使用 RSA存储p、q或φ,因为它们可以让您轻松地从公钥中找出私钥。
一般来说,不要在getZZZ
方法中计算
您应该在构造函数方法中找出n和e(以及d,但前提是它是私钥),并仅将它们存储在实例变量中。然后,您可以使用getN()
andgetE()
方法来获取预先计算的实例变量。例如(您不必使用此代码,它只是提供一个想法):
public class RSA {
private final BigInteger n;
private final BigInteger e;
private final BigInteger d;
public RSA(final BigInteger p, final BigInteger q) {
this.n = p.multiply(q);
// Calculate phi
final BigInteger pMinusOne = p.subtract(BigInteger.ONE);
final BigInteger qMinusOne = q.subtract(BigInteger.ONE);
final BigInteger phi = pMinusOne.multiply(qMinusOne);
// Calculate e
BigInteger e = BigInteger.valueOf(3L);
while (! phi.gcd(e).equals(BigInteger.ONE)) {
e = e.add(BigInteger.ONE);
}
this.e = e;
// Calculate d
this.d = e.modInverse(phi);
}
public BigInteger getN() {
return n;
}
public BigInteger getE() {
return e;
}
public BigInteger getD() {
return d;
}
}
推荐阅读
- javascript - 尝试使用 Javascript 查询 MongoDB,返回空
- java - RecyclerView 中的褪色边缘
- c++ - 望远镜调度
- php - 如何将sql查询转换为laravel ORM查询,如果不存在则插入
- powerbi - 如何在 Power BI 自定义主题中设置圆角半径?
- github-for-windows - 忽略已提交到 GitHub for Windows 中的 Git 存储库的文件
- postgresql - 如何按标识符分组并在 postgreSQL 中创建 JSON 对象数组?
- c++ - 如何将 unsigned short 转换为 unsigned char 并将值存储在字符串中
- angular - 当我在 Angular 8 中加载父组件时,我的子组件有没有初始化?
- c++ - 似乎无法将我的头文件与链表中的 cpp 文件连接起来