我使用 JShell 来演示仅使用 Java 的 BigInteger 生成基本的公私钥:
jshell> import java.math.BigInteger;
jshell> var rnd = new java.security.SecureRandom();
rnd ==> Hash_DRBG,SHA-256,128,reseed_only
首先我们需要两个素数
jshell> var p1 = BigInteger.probablePrime(512, rnd);
p1 ==> 1176110601168217581401499298469596353224364190716 ... 72507270343325790065694831
jshell> var p2 = BigInteger.probablePrime(512, rnd);
p2 ==> 1001341560055006431459083188828513502474297271020 ... 34378293673605844490263567
接下来我们计算公钥。 0x10001 是公钥的常用指数。
jshell> var n = p1.multiply(p2);
n ==> 1177688424171014462551464978852125044384293220079 ... 24824881562893076179522177
jshell> var e = BigInteger.valueOf(0x10001);
e ==> 65537
公钥是e 和n。
现在是私处。
jshell> var phi = p1.subtract(BigInteger.ONE).multiply(p2.subtract(BigInteger.ONE));
phi ==> 1177688424171014462551464978852125044384293220079 ... 17939317545961441623563780
jshell> var d = e.modInverse(phi);
d ==> 7023685818262702180949167670691999860354377649273 ... 38390163809778429090416313
私钥现在是d 和n。
让我们测试一下:
jshell> var secret = BigInteger.valueOf(1337);
secret ==> 1337
jshell> var enc = secret.modPow(e, n);
enc ==> 1059982071031392497566614763259148320406936402012 ... 39171914529632475117049800
jshell> enc.modPow(d, n);
$11 ==> 1337
我们可以通过网络发送enc,在不知道私钥的情况下,任何人都无法解密它。好吧,至少在理论上。在实践中,您应该填充您的消息。