使用Java中的RSA算法加密字符串的问题

时间:2011-04-28 12:48:17

标签: java string encryption rsa biginteger

我正在尝试采用RSA算法来加密String对象,但似乎BigInteger - >字符串和字符串 - > BigInteger转换无法正常运行。这是我的代码:

public class RSAEncryptor {

    private BigInteger n, d, e;

    public RSAEncryptor(int bitlen) {
        SecureRandom r = new SecureRandom();
        BigInteger p = new BigInteger(bitlen / 2, 100, r);
        BigInteger q = new BigInteger(bitlen / 2, 100, r);
        n = p.multiply(q);
        BigInteger m = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
        e = new BigInteger("3");
        while (m.gcd(e).intValue() > 1) {
            e = e.add(new BigInteger("2"));
        }
        d = e.modInverse(m);
    }

    public String encrypt(String message) {
        BigInteger plaintext = new BigInteger(message.getBytes());
        return new String(plaintext.modPow(e, n).toByteArray());
    }

    public String decrypt(String message) {
        BigInteger plaintext = new BigInteger(message.getBytes());
        return new String(plaintext.modPow(d, n).toByteArray());
    }
}

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        RSAEncryptor encryptor = new RSAEncryptor(64);

        String source = "1";
        String crypted = encryptor.encrypt(source);
        System.out.println(crypted);
        String decrypted = encryptor.decrypt(crypted);
        System.out.println(decrypted);
    }
}

它不会打印出预期的内容,奇怪的是每次输出都不同。难道我做错了什么?谢谢

3 个答案:

答案 0 :(得分:2)

加密邮件是任意byte[],无法保证可以使用特定字符编码将其正确转换为String,因此无需将其转换为String。< / p>

另一个技巧是plaintext应该小于n,否则算法会产生垃圾。当满足这个条件时,它对我来说很好。

另一个可能的问题是,当消息的第一个字节大于或等于0x80时,将产生负plaintext。可以通过在将消息转换为BigInteger之前将零字节添加到消息的字节来解决,并在逆转换期间剥离该字节。

答案 1 :(得分:0)

提示:getBytes与消息的字符串值有什么不同? 你为什么不做BigInteger(消息); ?

答案 2 :(得分:0)

import java.math.BigInteger;     
import java.security.SecureRandom;

public class RSA {  
   private final static BigInteger one      = new BigInteger("1");  
   private final static SecureRandom random = new SecureRandom();

   private BigInteger privateKey;  
   private BigInteger publicKey;  
   private BigInteger modulus;   

   // generate an N-bit (roughly) public and private key  
   RSA(int N) {  
      BigInteger p = BigInteger.probablePrime(N/2, random);  
      BigInteger q = BigInteger.probablePrime(N/2, random);   
      BigInteger phi = (p.subtract(one)).multiply(q.subtract(one));       
      modulus    = p.multiply(q);                                          
      publicKey  = new BigInteger("65537");       
   // common value in practice = 2^16 + 1
      privateKey = publicKey.modInverse(phi);   
   }


   BigInteger encrypt(BigInteger message) {    
      return message.modPow(publicKey, modulus);    
   }  

   BigInteger decrypt(BigInteger encrypted) {     
      return encrypted.modPow(privateKey, modulus);    
   }    

   public String toString() {    
      String s = "";    
      s += "public  = " + publicKey  + "\n";   
      s += "private = " + privateKey + "\n";    
      s += "modulus = " + modulus;    
      return s;    
   }    

   public static void main(String[] args) {    
      int N = Integer.parseInt(args[0]);    
      RSA key = new RSA(N);    
      System.out.println(key);    
      // create random message, encrypt and decrypt   
      BigInteger message = new BigInteger(N-1, random);   
      //// create message by converting string to integer   
      // String s = "test";    
      // byte[] bytes = s.getBytes();    
      // BigInteger message = new BigInteger(s);    
      BigInteger encrypt = key.encrypt(message);    
      BigInteger decrypt = key.decrypt(encrypt);    
      System.out.println("message   = " + message);    
      System.out.println("encrpyted = " + encrypt);    
      System.out.println("decrypted = " + decrypt);    
   }     
}