我正在尝试在Java中使用RSA加密。
我正在生成一个公共密钥,并使用它来加密文本。我的问题是,当我两次输入相同的文本和相同的密钥时,加密结果是不同的。这意味着我无法使用加密来测试输入的文本是否等于先前加密的存储结果。
这是我的加密类:
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
/**
* The class encrypts text using an RSA algorithm.
*
*/
public class RSAEncryption {
//RSA algorithm
private final String ALGORITHM = "RSA";
/**
* The generateKey method generates a public key for use in RSA encryption.
* @return key a PublicKey for use in RSA encryption.
*/
public PublicKey generateKey(){
KeyPair key = null;
KeyPairGenerator keyGen;
try {
keyGen = KeyPairGenerator.getInstance(ALGORITHM); //gets instance of the alogrithm
keyGen.initialize(1024); //a 1021 bit key
key = keyGen.generateKeyPair(); //makes a pair
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return key.getPublic(); //returns the public key. Private key never stored.
}
/**
* The encrypt method takes in text and a key and encrypts the text using the RSA encryption algorithm.
* @params text a String, the text to encrypt.
* @params key a PublicKey to use in encryption.
* @returns encryptedText a byte array representing the result of the encryption.
public byte[] encrypt(String text, PublicKey key){
byte[] encryptedText = null;
Cipher cipher;
try {
cipher = Cipher.getInstance(ALGORITHM); //gets instance of RSA
cipher.init(Cipher.ENCRYPT_MODE, key); //in encryption mode with the key
encryptedText = cipher.doFinal(text.getBytes()); //carry out the encryption
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return encryptedText; //return encrypted result
}
/**
* The authenticate method checks if entered text, once encrypted, matches the stored byte[].
* @param text a String, the text to encrypt.
* @param stored a byte[], the result of a prior encryption.
* @param key a PublicKey, a result of the generateKey method.
* @return boolean, true if the text is valid, false otherwise.
*/
public boolean authenticate(String text, byte[] stored, PublicKey key){
byte[] encryptText = encrypt(text,key); //encrypt the entered text
return Arrays.equals(stored, encryptText); //check if the stored and entered byte[] are the same.
}
}
我已经为此编写了JUnit测试:
import static org.junit.Assert.*;
import java.security.PublicKey;
import java.util.Arrays;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class RSAEncryptionTest {
RSAEncryption cipher;
String text;
@Before
public void setUp(){
cipher = new RSAEncryption();
text = "text";
}
@Test
public void testEncryptionGenerateKeyGeneratesANewKeyWhenCalled(){
PublicKey key = cipher.generateKey();
assertEquals(false,key.equals(cipher.generateKey()));
}
@Test
public void testEncryptionEncryptMethodRepeatablyEncrypts(){
PublicKey key = cipher.generateKey();
byte[] encrypted = cipher.encrypt(text,key);
Assert.assertArrayEquals(encrypted, cipher.encrypt(text,key));
//test fails
}
@Test
public void testEncryptionAuthenticateMethodReturnsTrueWhenValidTextPassedIn(){
PublicKey key = cipher.generateKey();
byte[] encrypted = cipher.encrypt(text,key);
assertEquals(true,cipher.authenticate(text,encrypted,key));
//test fails
}
@Test
public void testEncryptionAuthenticateMethodReturnsFalseWhenInvalidTextPassedIn(){
PublicKey key = cipher.generateKey();
byte[] encrypted = cipher.encrypt(text,key);
assertEquals(false,cipher.authenticate("text1",encrypted,key));
}
}
第二和第三次测试失败。
有什么想法如何使用RSA重复加密文本吗?
RSA是一种公共密钥加密方案。听起来您实际上想使用哈希算法(例如SHA-256或SHA-512)。我之所以这样说是因为您说:
这意味着我无法使用加密来测试输入的文本是否等于先前加密的存储结果。
如果这是您的目标,则应使用哈希算法。根据设计,RSA加密应包括一个填充步骤,以确保密文不同:
为了避免这些问题,实际的RSA实现通常在对值m进行加密之前将某种形式的结构化随机填充嵌入到值m中。这种填充确保m不会落入不安全的明文范围内,并且给定的消息一旦被填充,将被加密为大量不同的可能密文之一。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句