Paw*_*wan 4 java android cryptography rsa key-generator
这是我的代码片段:
int eValue = 79, t;
int bitLength = 1024; // KeySize
BigInteger e = new BigInteger(Integer.toString(eValue));
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(bitLength);
KeyPair kp = kpg.generateKeyPair();
KeyFactory kfactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec kspec = (RSAPublicKeySpec) kfactory.getKeySpec(kp.getPublic(),
RSAPublicKeySpec.class);
System.out.println("Byte Length is : " + kspec.getModulus().toByteArray().length);
String testString;
try {
testString = new String (kspec.getModulus().toByteArray() , "ISO-8859-1");
StringBuilder tt = new StringBuilder();
for(t =0 ; t< testString.length() ; t++)
{
tt.append((int) testString.charAt(t)+",");
}
String encryptedBytes = tt.toString();
System.out.println("Mod is : " + encryptedBytes);
}catch (Exception ex) {
// TODO: handle exception
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
Byte Length is : 129
Mod is : 0,190,193,141,230,128,124,6,201,254,135,66,162,65,147,160,76,160,181,7,141,113,8,57,193,185,206,42,125,9,169,209,124,74,233,151,10,128,180,35,24,206,213,32,48,4,39,178,60,10,249,151,50,218,220,11,124,72,64,148,135,251,133,23,54,171,25,202,157,28,21,39,239,234,48,56,79,36,127,59,203,108,189,232,216,231,237,237,90,253,19,118,29,18,142,126,254,193,189,82,15,126,139,136,45,31,133,242,187,81,62,52,5,23,11,217,171,233,7,137,115,30,93,206,236,31,196,111,153
Run Code Online (Sandbox Code Playgroud)
对于1024位长度,密钥模数应该是128字节,对于2048,它应该是256,但是我得到额外的一个字节(总是在第一个字节添加0),需要帮助重新开始这个...
谢谢,Pawan
启动时00h值字节的原因是因为BigInteger.toByteArray()返回带符号的表示.只要以比特为单位的密钥长度为N*8(或密钥长度%8 = 0),则RSA模数的带符号表示将始终以开始时的00h值字节为特征.
如果初始字节为零,只需将其复制到密钥长度的数组(以字节为单位)即可删除.请注意,如果您有一个私有指数,它也可能短于以字节为单位的密钥长度,因此将其复制到新字节数组的末尾.通常,这种方法称为I2OS或I2O(整数到八位字符串),其中八位字节sting(java中的字节数组)具有指定的长度.
/**
* Encodes the given value as a unsigned Big Endian within an octet string
* of octetStringSize bytes.
*
* @param i
* the integer to encode
* @param octetStringSize
* the number of octets in the octetString returned
* @return the encoding of i
* @throws IllegalArgumentException
* if the given integer i is negative
* @throws IllegalArgumentException
* if the octetStringSize is zero or lower
* @throws IllegalArgumentException
* if the given BigInteger does not fit into octetStringSize
* bytes
*/
public static byte[] integerToOctetString(final BigInteger i,
final int octetStringSize) {
// throws NullPointerException if i = null
if (i.signum() < 0) {
throw new IllegalArgumentException(
"argument i should not be negative");
}
if (octetStringSize <= 0) {
throw new IllegalArgumentException("octetStringSize argument ("
+ octetStringSize
+ ") should be higher than 0 to store any integer");
}
if (i.bitLength() > octetStringSize * Byte.SIZE) {
throw new IllegalArgumentException("argument i (" + i
+ ") does not fit into " + octetStringSize + " octets");
}
final byte[] signedEncoding = i.toByteArray();
final int signedEncodingLength = signedEncoding.length;
if (signedEncodingLength == octetStringSize) {
return signedEncoding;
}
final byte[] unsignedEncoding = new byte[octetStringSize];
if (signedEncoding[0] == (byte) 0x00) {
// skip first padding byte to create a (possitive) unsigned encoding for this number
System.arraycopy(signedEncoding, 1, unsignedEncoding,
octetStringSize - signedEncodingLength + 1,
signedEncodingLength - 1);
} else {
System.arraycopy(signedEncoding, 0, unsignedEncoding,
octetStringSize - signedEncodingLength,
signedEncodingLength);
}
return unsignedEncoding;
}
/**
* Returns a BigInteger that is the value represented by the unsigned, Big
* Endian encoding within the given octetString.
*
* @param octetString
* the octetString containing (only) the encoding
* @return the value represented by the octetString
*/
public static BigInteger octetStringToInteger(final byte[] octetString) {
// arguments are signum, magnitude as unsigned, Big Endian encoding
return new BigInteger(1, octetString);
}
/**
* Returns the minimum number of bytes required to directly store the given
* number of bits.
*
* @param bitSize
* the bitSize
* @return the size as a number of bytes
* @throws IllegalArgumentException
* if the given bitSize argument is negative
*/
public static int bitSizeToByteSize(final int bitSize) {
if (bitSize < 0) {
throw new IllegalArgumentException("bitSize (" + bitSize
+ " should not be negative");
}
return (bitSize + Byte.SIZE - 1) / Byte.SIZE;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用 Arrays.deepToString() 直接打印字节数组:
String encryptedBytes = Arrays.deepToString(new Object[] { kspec.getModulus().toByteArray() })
Run Code Online (Sandbox Code Playgroud)
我怀疑您在处理有符号数字和无符号数字时遇到问题。128 位模数是无符号的,但将其存储在 BigInteger 中有时可能需要 129 位,因此需要额外的字节。