問題描述
我正在嘗試制作一個(gè)涉及密碼學(xué)的簡單 Java 程序.
I am trying to make a simple Java program that involves cryptography.
首先,我從文件 clearmsg.txt 中讀取一個(gè) 32 字節(jié)的塊.然后我將此塊轉(zhuǎn)換為整數(shù),并將其用于加密.不幸的是,密文的大小不是靜態(tài)的;有時(shí)它返回 30 個(gè)字節(jié),有時(shí)返回 26 個(gè)字節(jié).這似乎與添加操作的結(jié)果無關(guān).
First I read a block of 32 bytes from file clearmsg.txt. Then I convert this block to integer number, and use it for encryption. Unfortunately the size of the ciphertext is not static; sometimes it returns 30 bytes and sometimes 26 bytes. This seems independent on result of add operation.
如何確保它變成 32 字節(jié)的密碼塊?如何向這個(gè)塊添加位/字節(jié)?因?yàn)楫?dāng)我嘗試解密這個(gè)塊時(shí),我需要讀取 32 個(gè)密文字節(jié).
How can I make sure it becomes a cipher block of 32 bytes? How add bits / bytes to this block? Because when I try decrypt this block I need to read 32 ciphertext bytes.
private void ENC_add() {
final File clearmsg = new File("F:/java_projects/clearmsg.txt");
final File ciphermsg = new File("F:/java_projects/ciphermsg.txt");
final byte[] block = new byte[32];
try {
final FileInputStream fis = new FileInputStream(clearmsg);
final FileOutputStream fcs = new FileOutputStream(ciphermsg);
int i;
while ((i = fis.read(block)) != -1) {
// Is this process true
// here M2 (Plain text) shuld be 32 byte
M2 = new BigInteger(block);
// here encrypt M2 by add k1 where k1 any number less than P
CM2 = M2.add(K1).mod(P);
// here my problem some time Cipher CM2 length 31 , some time CM2 length 32 ,some time CM2 length 30
System.out.println("THE CM2=" + CM2.toByteArray().Length);
fcs.write(CM2.toByteArray(), 0, i);
}
fcs.close();
}
catch (final IOException e) {
e.printStackTrace();
}
}
// Here problem for decrypt
private void DEC_ADD() {
// DECREPT METHOD
final File ciphermsg = new File("F:/java_projects/ciphermsg.txt");
final File clearmsg = new File("F:/java_projects/rciphermsg.txt");
final byte[] block = new byte[32];
try {
final FileInputStream fis = new FileInputStream(ciphermsg);
final FileOutputStream fos = new FileOutputStream(clearmsg);
int i;
while ((i = fis.read(block)) != -1) {
// CM2 NOT STATIC BITS NUMBER BECAUSE INDEPENDET ON RESULT ADDITIONAL AND PRIME NUMBER P through ENCRYPT
// Process
CM2 = new BigInteger(block);
// here RM2 is decrypt cipher (CM2) NOTE When encrypt above M2 WAS 32 bytes and Cipher CM2 was 30 bytes
// and When I read from file 32 bytes then this is my problem
RM2 = CM2.subtract(K1).mod(P);
fos.write(RM2.toByteArray(), 0, i);
}
fos.close();
System.out.println("THE RM2=" + CM2.bitLength());
} catch (final IOException e) {
e.printStackTrace();
}
}
推薦答案
對(duì)于加密,需要一個(gè)通常稱為 Integer to Octet String Primitive 或 I2OSP 的函數(shù).對(duì)于解密,您需要一個(gè) OS2IP 函數(shù)來轉(zhuǎn)換回整數(shù).我在密碼學(xué)姊妹網(wǎng)站上的回答中解釋了兩者.它們是 RSA PKCS#1 規(guī)范的一部分,在此處指定了 2.2 版.
For the encrypt a function is required that is normally called Integer to Octet String Primitive or I2OSP. For decryption you need an OS2IP function to convert back to integers. Both are explained in my answer on the cryptography sister site. They are part of the RSA PKCS#1 specifications, for which version 2.2 is specified here.
I2OSP 和 OS2IP 函數(shù)也用于其他加密原語.例如,它們可用于橢圓曲線密碼學(xué)以創(chuàng)建平面 ECDSA 簽名或 EC 公鑰表示.
The I2OSP and OS2IP functions are also used for other cryptographic primitives. For instance, they can be used for Elliptic Curve Cryptography to create flat ECDSA signatures or EC public key representations.
這些函數(shù)用于對(duì)給定大小的八位字節(jié)字符串(字節(jié)數(shù)組)進(jìn)行編碼/解碼.此大小通常與 RSA 加密的模數(shù)(在您的情況下為 P)的大小直接相關(guān).
These functions are used to encode/decode to an octet string (byte array) of a given size. This size is normally directly related to the size of the modulus (P in your case) of RSA encryption.
I2OSP 函數(shù)應(yīng)該這樣編碼:
The I2OSP function should be coded like this:
public static byte[] i2osp(final BigInteger i, final int size) {
if (size < 1) {
throw new IllegalArgumentException("Size of the octet string should be at least 1 but is " + size);
}
if (i == null || i.signum() == -1 || i.bitLength() > size * Byte.SIZE) {
throw new IllegalArgumentException("Integer should be a positive number or 0, no larger than the given size");
}
final byte[] signed = i.toByteArray();
if (signed.length == size) {
// (we are lucky, already the right size)
return signed;
}
final byte[] os = new byte[size];
if (signed.length < size) {
// (the dynamically sized array is too small, pad with 00 valued bytes at the left)
System.arraycopy(signed, 0, os, size - signed.length, signed.length);
return os;
}
// (signed representation too large, remove leading 00 valued byte)
System.arraycopy(signed, 1, os, 0, size);
return os;
}
當(dāng)然,要使用正確的大小八位字節(jié)/字節(jié),您首先應(yīng)該知道密鑰大小(以字節(jié)為單位).對(duì)于 RSA 公鑰或私鑰,這可以很容易地從模數(shù)中計(jì)算出來(如果它不直接可用,如在 Java JCA 中):
Of course, to use this with the correct size in octets / bytes you should first know the key size in bytes first. For an RSA public- or private key this can be easily calculated from the modulus (in case it is not directly available, as in the Java JCA):
public static int keySizeInOctets(RSAKey key) {
int keySizeBits = key.getModulus().bitLength();
int keySizeBytes = (keySizeBits + Byte.SIZE - 1) / Byte.SIZE;
return keySizeBytes;
}
請(qǐng)注意,RSAPublicKey
、RSAPrivateKey
和 RSAPrivateCrtKey
都擴(kuò)展了 RSAKey
,后者提供了對(duì)模數(shù)的訪問.因此,您可以直接使用這些類的實(shí)例作為此方法的參數(shù).當(dāng)然,Java 中的 RSA 提供程序在 Cipher
和 Signature
實(shí)現(xiàn)類中已經(jīng)包含了 I2OSP 和 OS2IP,但是從位大小到字節(jié)大小的轉(zhuǎn)換(沒有浮點(diǎn)計(jì)算)可以派上用場(chǎng).
Note that RSAPublicKey
, RSAPrivateKey
and RSAPrivateCrtKey
all extend RSAKey
which provides access to the modulus. So you can use instances of these classes directly as argument for this method. Of course, the RSA providers in Java already contain I2OSP and OS2IP within the Cipher
and Signature
implementation classes, but the conversion from bit size to byte size (without floating point calculations) could come in handy.
還好反轉(zhuǎn)功能沒那么復(fù)雜:
Fortunately, the reverse function is not as complicated:
public static BigInteger os2ip(final byte[] data, final int size) {
if (data.length != size) {
throw new IllegalArgumentException("Size of the octet string should be precisely " + size);
}
return new BigInteger(1, data);
}
我保留了大小驗(yàn)證,因此可以使用 預(yù)期八位字節(jié)大小調(diào)用它,即使計(jì)算本身不需要它.
I've kept in the size validation so it can be called with the expected octet size, even though it is not required for the calculation itself.
這篇關(guān)于java - 如何在java密碼學(xué)中將位插入塊中?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!