使用RSA算法以Java加密文本

盖伊·尼达姆(Guy Needham)

我正在尝试在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不会落入不安全的明文范围内,并且给定的消息一旦被填充,将被加密为大量不同的可能密文之一。

- http://en.wikipedia.org/wiki/RSA_%28algorithm%29

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用Java的RSA加密/解密

来自分类Dev

使用RSA算法字母'w','x','y','z'进行加密

来自分类Dev

如何使用RSA和AES算法加密和解密文件

来自分类Dev

在Java中使用RSA加密SecretKey

来自分类Dev

如何使用ssh-rsa公钥加密文本?

来自分类Dev

如何使用RSA和OpenSSL加密消息/文本?

来自分类Dev

使用RSA加密哈希

来自分类Dev

使用rsa:2048创建的SSL证书是否使用SHA-2加密哈希算法?

来自分类Dev

使用Java进行RSA加密并使用JavaScript进行解密

来自分类Dev

使用Java的内置库进行简单的RSA加密

来自分类Dev

在Java中使用rsa加密和解密大文件

来自分类Dev

使用Java NetBeans对图像进行rsa加密和解密

来自分类Dev

Java 和 JavaScript 之间使用 OAEP 的 RSA 加密

来自分类Dev

Java卡加密异常RSA密钥加密

来自分类Dev

使用AES算法的图像加密

来自分类Dev

C#RSA使用给定的PKCS#1公钥加密文本

来自分类Dev

通过RSA算法对值进行加密和解密

来自分类Dev

RSA加密Java和解密Java

来自分类Dev

如何使用phpseclib进行加密和使用AES算法使用Java进行解密

来自分类Dev

使用Java库使用RSA加密创建JWT(Json Web令牌)?

来自分类Dev

RSA使用Pycrypto OAEP进行加密,并使用普通的旧Java进行解密

来自分类Dev

Android和Java中的RSA加密

来自分类Dev

RSA:在iOS中加密,在Java中解密

来自分类Dev

Javascript RSA加密到Java BouncyCastle解密

来自分类Dev

Javascript RSA加密到Java BouncyCastle解密

来自分类Dev

Android和Java中的RSA加密

来自分类Dev

使用现有公钥的RSA加密

来自分类Dev

使用RSA python加密消息时出错

来自分类Dev

在Swift中使用RSA证书加密