您正在滚动自己的加密货币。
做好失败的准备。您最终编写的代码实际上是安全的可能性是无限大的。非常、非常、非常很容易出错。这些错误几乎总是极难测试(例如,您的算法可能会根据处理不同输入所需的时间来泄漏信息,从而让攻击者在几个小时内找出密钥。您是否打算编写一个检查是否所有尝试解码任何内容的测试,无论是实际密文、损坏的密文、密文的一半、专门设计用于通过检查处理所需时间来尝试获取关键信息的精心设计的输入,以及随机 gobbledygook 都需要完全相同的时间? 你知道你需要测试什么样的精心设计的输入吗?)
关于定时攻击,具体来说,一旦你写了BigInteger,你几乎肯定输了。编写一个不受时间攻击影响的基于 BI 的算法几乎是不可能的。
专家会将所有密钥和加密算法中间体保存为byte[] 形式。
所以,你做错了。不要滚动你自己的加密货币,你会搞砸的。使用现有算法。
如果你真的,真的,真的想走这条路,你需要在开始之前学习,很多。首先分析大量现有实现。试着去摸索每一行,试着去摸索每一个动作。例如,密码哈希检查算法可能包含以下代码:
public boolean isEqual(byte[] a, byte[] b) {
if (a.length != b.length) throw new IllegalArgumentException("mismatched lengths");
int len = a.length;
boolean pass = true;
for (int i = 0; i < len; i++) {
if (a[i] != b[i]) pass = false;
}
return pass;
}
你可能会简单地得出结论:嗯。诡异的。我猜他们是从 C 或其他东西中复制它的,或者他们只是不知道他们可以完全删除该方法并用java.util.Arrays.equals(a, b); 替换它。哦,好吧,没关系。
你会错的 - 这就是我理解这一切的意思。假设没有错误。 Arrays.equals 可以受到时间攻击(它运行所花费的时间告诉你一些事情:不匹配越早,它返回的速度越快。这个方法需要相同的时间,但只有在两个输入是长度相等,因此如果发生这种情况,它会抛出而不是返回看似明显的false)。
如果您花这么多时间分析它们,那么您将多次讨论这个问题。
因此,在所有上下文中:
这个答案是火箭筒。你会炸掉你的脚。您不想编写此代码。你不想做你想做的事。 BigInteger 是错误的方法。
new BigInteger(8 * 40, secureRandom); 将正确完成工作:生成一个介于 (0 和 2^320-1) 之间的随机数,包括 40 个字节。不多也不少。
可以按如下方式生成 40 字节的随机性:
byte[] key = new byte[40];
secureRandom.nextBytes(key);
但这仍然是一个严重的错误,除非你真的,真的,真的知道你在做什么(尝试找到一个有可靠作者或经过专家审查的现有实现)。