我正在开发一个程序,它是RSA加密算法的一种实现,就像个人练习一样,它不保护任何人的信息或任何东西。我试图理解明文通道如何被数字解释,允许它被加密。据我所知,大多数UTF-8字符最终只使用1个字节的空间,而不是人们可能想到的2个字节,但就此而言。继承我的代码:
BigInteger ONE = new BigInteger("1");
SecureRandom rand = new SecureRandom();
BigInteger d, e, n;
BigInteger p = BigInteger.probablePrime(128, rand);
BigInteger q = BigInteger.probablePrime(128, rand);
BigInteger phi = (p.subtract(ONE)).multiply(q.subtract(ONE));
n = p.multiply(q);
e = new BigInteger("65537");
d = e.modInverse(phi);
String string = "test";
BigInteger plainText = new BigInteger(string.getBytes("UTF-8"));
BigInteger cipherText = plainText.modPow(e, n);
BigInteger originalMessage = cipherText.modPow(d, n);
String decrypted = new String(originalMessage.toByteArray(),"UTF-8");
System.out.println("original: " + string);
System.out.println("decrypted: " + decrypted);
System.out.println(plainText);
System.out.println(cipherText);
System.out.println(originalMessage);
System.out.println(string.getBytes("UTF-8"));
byte byteArray[] = string.getBytes("UTF-8");
for(byte littleByte:byteArray){
System.out.println(littleByte);
}
输出:
original: test
decrypted: test
1952805748
16521882695662254558772281277528769227027759103787217998376216650996467552436
1952805748
[B@60d70b42
116
101
115
116
也许更具体地说,我想知道这一行:
BigInteger plainText = new BigInteger(string.getBytes("UTF-8"));
“test”的每一个字母都有一个值,它们在这里加在一起吗?比如说t = 1,e = 2,s = 3,t = 1,例如,如果你从那个字符串得到字节,你最终得到7还是像1231那样放在一起的值?为什么
BigInteger plainText = new BigInteger(string.getBytes("UTF-8"));
输出1952805748
答案 0 :(得分:2)
我试图理解明文通道是如何被数字解释的,允许它被加密。
这真的归结为理解这条线的作用:
BigInteger plainText = new BigInteger(string.getBytes("UTF-8"));
让我们分解。
我们从字符串(string
)开始。 Java字符串是表示为Unicode代码点的字符序列(以UCS-16编码...)。
getBytes("UTF-8")
然后将字符编码为字节序列,并在新分配的字节数组中返回它们。
BigInteger(byte[])
构造函数将该字节数组解释为数字。正如javadoc所说:
将包含BigInteger的二进制补码二进制表示的字节数组转换为BigInteger。输入数组是 假设是大端字节顺序:最重要的字节是 在第0个元素中。
这里使用的方法不是给出一个有意义的有意义的数字,只是对应于字节编码的字符串。从字节数组到数字只是将字节视为一个位序列,表示2的补码形式的整数...这是现代硬件上整数的最常见表示。
关键是从文本到(未加密的)BigInteger的转换是无损且可逆的。可以使用具有这些属性的任何其他转换。
参考文献:
BigInteger(byte[])
String.getBytes(String)
我还不太明白为什么" test",116,101,115,116中的每个字符的UTF-8值如何组合在一起形成1952805748?
看模式?
答案 1 :(得分:1)
答案在输出中,“test”被编码为4个字节的数组[116,101,115,116]。然后由BigInteger将其作为二进制整数表示。可以通过这种方式计算值
value = (116 << 24) + (101 << 16) + (115 << 8) + 116;