2012-02-01 47 views
1
public class MyEncrypt { 

    public void saveToFile(String fileName, BigInteger mod, BigInteger exp) throws IOException { 
     ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName))); 
      try { 
       oout.writeObject(mod); 
       oout.writeObject(exp); 
      } catch (Exception e) { 
      throw new IOException("Unexpected error", e); 
      } finally { 
      oout.close(); 
      } 
    } 

    public static void main(String[] args) throws Exception { 
       MyEncrypt myEncrypt = new MyEncrypt(); 
     KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
     kpg.initialize(128); 
     KeyPair kp = kpg.genKeyPair(); 
     RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic(); 
     RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate(); 
     KeyFactory fact = KeyFactory.getInstance("RSA");   
     RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class); 
     RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class); 

     myEncrypt.saveToFile("public.key", pub.getModulus(), pub.getPublicExponent()); 
     myEncrypt.saveToFile("private.key", priv.getModulus(), priv.getPrivateExponent()); 
     String encString = myEncrypt.bytes2String(myEncrypt.rsaEncrypt("pritesh".getBytes())); 
     System.out.println("encrypted : " + encString); 
     String decString = myEncrypt.bytes2String(myEncrypt.rsaDecrypt(encString.getBytes())); 
     System.out.println("decrypted : " + decString); 
    } 

    PublicKey readKeyFromFile(String keyFileName) throws Exception { 
     InputStream in = new FileInputStream(keyFileName); 
     ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in)); 
     try { 
     BigInteger m = (BigInteger) oin.readObject(); 
     BigInteger e = (BigInteger) oin.readObject(); 
     RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e); 
     KeyFactory fact = KeyFactory.getInstance("RSA"); 
     PublicKey pubKey = fact.generatePublic(keySpec); 
     return pubKey; 
     } catch (Exception e) { 
     throw new RuntimeException("Spurious serialisation error", e); 
     } finally { 
     oin.close(); 
     } 
    } 

    PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception { 
     InputStream in = new FileInputStream(keyFileName); 
     ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in)); 
     try { 
     BigInteger m = (BigInteger) oin.readObject(); 
     BigInteger e = (BigInteger) oin.readObject(); 
     RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e); 
     KeyFactory fact = KeyFactory.getInstance("RSA"); 
     PrivateKey pubKey = fact.generatePrivate(keySpec); 
     return pubKey; 
     } catch (Exception e) { 
     throw new RuntimeException("Spurious serialisation error", e); 
     } finally { 
     oin.close(); 
     } 
    } 

    public byte[] rsaEncrypt(byte[] data) throws Exception { 
     byte[] src = new byte[] { (byte) 0xbe, (byte) 0xef }; 
     PublicKey pubKey = this.readKeyFromFile("public.key"); 
     Cipher cipher = Cipher.getInstance("RSA"); 
     cipher.init(Cipher.ENCRYPT_MODE, pubKey); 
     byte[] cipherData = cipher.doFinal(data); 
     return cipherData; 
    } 

    public byte[] rsaDecrypt(byte[] data) throws Exception { 
     byte[] src = new byte[] { (byte) 0xbe, (byte) 0xef }; 
     PrivateKey pubKey = this.readPrivateKeyFromFile("private.key"); 
     Cipher cipher = Cipher.getInstance("RSA"); 
     cipher.init(Cipher.DECRYPT_MODE, pubKey); 
     byte[] cipherData = cipher.doFinal(data); 
     return cipherData; 
    } 

    private String bytes2String(byte[] bytes) { 
     StringBuilder string = new StringBuilder(); 
     for (byte b: bytes) { 
       String hexString = Integer.toHexString(0x00FF & b); 
       string.append(hexString.length() == 1 ? "0" + hexString : hexString); 
     } 
     return string.toString(); 
    } 
} 

我收到此錯誤:問題在RSA加密的Java類

Exception in thread "main" java.security.InvalidParameterException: RSA keys must be at least 512 bits long 
    at sun.security.rsa.RSAKeyPairGenerator.initialize(RSAKeyPairGenerator.java:70) 
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:631) 
    at java.security.KeyPairGenerator.initialize(KeyPairGenerator.java:340) 
    at MyEncrypt.main(MyEncrypt.java:42) 

我從http://www.javamex.com/tutorials/cryptography/rsa_encryption_2.shtml例如


public class MyEncrypt {

static final String HEXES = "ABCDEF"; 
byte[] buf = new byte[1024];  

public void saveToFile(String fileName, BigInteger mod, BigInteger exp) throws IOException { 
    ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName))); 
     try { 
      oout.writeObject(mod); 
      oout.writeObject(exp); 
     } catch (Exception e) { 
     throw new IOException("Unexpected error", e); 
     } finally { 
     oout.close(); 
     } 
} 

public static void main(String[] args) throws Exception {  
      MyEncrypt myEncrypt = new MyEncrypt(); 
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
    kpg.initialize(2048); 
    KeyPair kp = kpg.genKeyPair(); 
    RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic(); 
    RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate(); 
    KeyFactory fact = KeyFactory.getInstance("RSA");   
    RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class); 
    RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class); 

    myEncrypt.saveToFile("public.key", pub.getModulus(), pub.getPublicExponent()); 
    myEncrypt.saveToFile("private.key", priv.getModulus(), priv.getPrivateExponent()); 
    String encString = myEncrypt.rsaEncrypt("pritesh"); 
    System.out.println("encrypted : " + encString); 
    String decString = myEncrypt.rsaDecrypt(encString); 
    System.out.println("decrypted : " + decString); 

    String main_file_path = "resume.doc";     
    String main_encrypt_file_path = "encrypt.doc"; 
    String main_decrypt_file_path = "decrypt.doc"; 

    myEncrypt.rsaEncrypt(new FileInputStream(main_file_path),new FileOutputStream(main_encrypt_file_path)); 
      // Decrypt 
    myEncrypt.rsaDecrypt(new FileInputStream(main_encrypt_file_path),new FileOutputStream(main_decrypt_file_path)); 
} 

PublicKey readKeyFromFile(String keyFileName) throws Exception { 
    InputStream in = new FileInputStream(keyFileName); 
    ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in)); 
    try { 
    BigInteger m = (BigInteger) oin.readObject(); 
    BigInteger e = (BigInteger) oin.readObject(); 
    RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e); 
    KeyFactory fact = KeyFactory.getInstance("RSA"); 
    PublicKey pubKey = fact.generatePublic(keySpec); 
    return pubKey; 
    } catch (Exception e) { 
    throw new RuntimeException("Spurious serialisation error", e); 
    } finally { 
    oin.close(); 
    } 
} 

PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception { 
    InputStream in = new FileInputStream(keyFileName); 
    ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in)); 
    try { 
    BigInteger m = (BigInteger) oin.readObject(); 
    BigInteger e = (BigInteger) oin.readObject(); 
    RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e); 
    KeyFactory fact = KeyFactory.getInstance("RSA"); 
    PrivateKey pubKey = fact.generatePrivate(keySpec); 
    return pubKey; 
    } catch (Exception e) { 
    throw new RuntimeException("Spurious serialisation error", e); 
    } finally { 
    oin.close(); 
    } 
} 

public String rsaEncrypt(String plaintext) throws Exception {  
    PublicKey pubKey = this.readKeyFromFile("public.key"); 
    Cipher cipher = Cipher.getInstance("RSA"); 
    cipher.init(Cipher.ENCRYPT_MODE, pubKey); 
    byte[] ciphertext = cipher.doFinal(plaintext.getBytes("UTF-8")); 
    return this.byteToHex(ciphertext); 
} 

public void rsaEncrypt(InputStream in, OutputStream out) throws Exception { 
    try {      
     PublicKey pubKey = this.readKeyFromFile("public.key"); 
     Cipher cipher = Cipher.getInstance("RSA"); 
     cipher.init(Cipher.ENCRYPT_MODE, pubKey); 
     // Bytes written to out will be encrypted 
     out = new CipherOutputStream(out, cipher); 

     // Read in the cleartext bytes and write to out to encrypt 
     int numRead = 0; 
     while ((numRead = in.read(buf)) >= 0){ 
      out.write(buf, 0, numRead); 
     } 
     out.close(); 
    } 
    catch (java.io.IOException e){ 
     e.printStackTrace(); 
    } 
} 

public void rsaDecrypt(InputStream in, OutputStream out) throws Exception { 
    try {     
     PrivateKey pubKey = this.readPrivateKeyFromFile("private.key"); 
     Cipher dcipher = Cipher.getInstance("RSA"); 
     dcipher.init(Cipher.DECRYPT_MODE, pubKey); 
     // Bytes read from in will be decrypted 
     in = new CipherInputStream(in, dcipher); 

     // Read in the decrypted bytes and write the cleartext to out 
     int numRead = 0; 
     while ((numRead = in.read(buf)) >= 0) { 
      out.write(buf, 0, numRead); 
     } 
     out.close(); 
    } catch (java.io.IOException e) { 
     e.printStackTrace(); 
    } 
} 

public String rsaDecrypt(String hexCipherText) throws Exception {  
    PrivateKey pubKey = this.readPrivateKeyFromFile("private.key"); 
    Cipher cipher = Cipher.getInstance("RSA"); 
    cipher.init(Cipher.DECRYPT_MODE, pubKey);  
    String plaintext = new String(cipher.doFinal(this.hexToByte(hexCipherText)), "UTF-8"); 
    return plaintext; 
} 

public static String byteToHex(byte [] raw) { 
    if (raw == null) { 
     return null; 
    } 
    final StringBuilder hex = new StringBuilder(2 * raw.length); 
    for (final byte b : raw) { 
     hex.append(HEXES.charAt((b & 0xF0) >> 4)) 
     .append(HEXES.charAt((b & 0x0F))); 
    } 
    return hex.toString(); 
} 

public static byte[] hexToByte(String hexString){ 
    int len = hexString.length(); 
    byte[] ba = new byte[len/2]; 
    for (int i = 0; i < len; i += 2) { 
     ba[i/2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i+1), 16)); 
    } 
    return ba; 
} 

}

它與效果很好使這個類文本文件,但給文件像docx和視頻任何想法問題?

+0

獲得更長的鍵 - 512位,要精確。 – duffymo 2012-02-01 10:34:27

+0

+1爲一個完整的工作示例 – 2012-02-02 09:41:51

回答

0

最終ANS

public class MyEncrypt {

public static final int AES_Key_Size = 128; 

Cipher pkCipher, aesCipher; 
byte[] aesKey; 
SecretKeySpec aeskeySpec; 

public static void main(String[] args) throws Exception { 
    //MyEncrypt.createRSAKeys(); //call to generated RSA keys 
    MyEncrypt secure = new MyEncrypt(); 
    // to encrypt a file 
    secure.makeKey(); 
    secure.saveKey(new File("keys/ase.key"), "keys/public.key"); 
    secure.encrypt(new File("test/sample.pdf"), new File("test/encrypt_sample.pdf")); 

    // to decrypt it again 
    secure.loadKey(new File("keys/ase.key"), "keys/private.key"); 
    secure.decrypt(new File("test/encrypt_sample.pdf"), new File("test/decrypted_sample.pdf")); 
} 

/** 
* Constructor: creates ciphers 
*/ 
public MyEncrypt() throws GeneralSecurityException { 
    // create RSA public key cipher 
    pkCipher = Cipher.getInstance("RSA"); 
    // create AES shared key cipher 
    aesCipher = Cipher.getInstance("AES"); 
} 

public static void createRSAKeys() throws Exception { 
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
    kpg.initialize(512); 
    KeyPair kp = kpg.genKeyPair(); 
    RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic(); 
    RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate(); 
    KeyFactory fact = KeyFactory.getInstance("RSA");   
    RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class); 
    RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class); 
    saveToFile("keys/public.key", pub.getModulus(), pub.getPublicExponent()); 
    saveToFile("keys/private.key", priv.getModulus(), priv.getPrivateExponent()); 
    System.out.println("RSA public & private keys are generated"); 
} 

private static void saveToFile(String fileName, BigInteger mod, BigInteger exp) throws IOException { 
    ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName))); 
     try { 
      oout.writeObject(mod); 
      oout.writeObject(exp); 
     } catch (Exception e) { 
     throw new IOException("Unexpected error", e); 
     } finally { 
     oout.close(); 
     } 
} 

/** 
* Creates a new AES key 
*/ 
public void makeKey() throws NoSuchAlgorithmException { 
    KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
    kgen.init(AES_Key_Size); 
    SecretKey key = kgen.generateKey(); 
    aesKey = key.getEncoded(); 
    aeskeySpec = new SecretKeySpec(aesKey, "AES"); 
} 

/** 
* Encrypts the AES key to a file using an RSA public key 
*/ 
public void saveKey(File out, String publicKeyFile) throws IOException, GeneralSecurityException { 
     try { 
      // read public key to be used to encrypt the AES key 
      byte[] encodedKey = new byte[(int)publicKeyFile.length()]; 
      new FileInputStream(publicKeyFile).read(encodedKey); 

      // create public key 
      //X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey); 
      //KeyFactory kf = KeyFactory.getInstance("RSA"); 
      //PublicKey pk = kf.generatePublic(publicKeySpec); 
      PublicKey pk = this.readPublicKeyFromFile(publicKeyFile); 

      // write AES key 
      pkCipher.init(Cipher.ENCRYPT_MODE, pk); 
      CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out), pkCipher); 
      os.write(aesKey); 
      os.close();  
     } catch (Exception e) { 
      //throw new Exception("Saving key exception", e);  
     } 

} 

private PublicKey readPublicKeyFromFile(String keyFileName) throws Exception { 
    InputStream in = new FileInputStream(keyFileName); 
    ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in)); 
    try { 
    BigInteger m = (BigInteger) oin.readObject(); 
    BigInteger e = (BigInteger) oin.readObject(); 
    RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e); 
    KeyFactory fact = KeyFactory.getInstance("RSA"); 
    PublicKey pubKey = fact.generatePublic(keySpec); 
    return pubKey; 
    } catch (Exception e) { 
    throw new RuntimeException("Spurious serialisation error", e); 
    } finally { 
    oin.close(); 
    } 
} 

private PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception { 
    InputStream in = new FileInputStream(keyFileName); 
    ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in)); 
    try { 
    BigInteger m = (BigInteger) oin.readObject(); 
    BigInteger e = (BigInteger) oin.readObject(); 
    RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e); 
    KeyFactory fact = KeyFactory.getInstance("RSA"); 
    PrivateKey pubKey = fact.generatePrivate(keySpec); 
    return pubKey; 
    } catch (Exception e) { 
    throw new RuntimeException("Spurious serialisation error", e); 
    } finally { 
    oin.close(); 
    } 
} 

/** 
* Decrypts an AES key from a file using an RSA private key 
*/ 
public void loadKey(File in, String privateKeyFile) throws GeneralSecurityException, IOException { 
      try { 
       // read private key to be used to decrypt the AES key 
       byte[] encodedKey = new byte[(int)privateKeyFile.length()]; 
       new FileInputStream(privateKeyFile).read(encodedKey); 

       // create private key 
       //PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey); 
       //KeyFactory kf = KeyFactory.getInstance("RSA"); 
       //PrivateKey pk = kf.generatePrivate(privateKeySpec); 
       PrivateKey pk = this.readPrivateKeyFromFile(privateKeyFile); 

       // read AES key 
       pkCipher.init(Cipher.DECRYPT_MODE, pk); 
       aesKey = new byte[AES_Key_Size/8]; 
       CipherInputStream is = new CipherInputStream(new FileInputStream(in), pkCipher); 
       is.read(aesKey); 
       aeskeySpec = new SecretKeySpec(aesKey, "AES");  
      } catch (Exception e) { 

      } 

    } 

/** 
* Encrypts and then copies the contents of a given file. 
*/ 
public void encrypt(File in, File out) throws IOException, InvalidKeyException { 
    aesCipher.init(Cipher.ENCRYPT_MODE, aeskeySpec); 

    FileInputStream is = new FileInputStream(in); 
    CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out), aesCipher); 

    copy(is, os); 

    os.close(); 
} 

/** 
* Decrypts and then copies the contents of a given file. 
*/ 
public void decrypt(File in, File out) throws IOException, InvalidKeyException { 
    aesCipher.init(Cipher.DECRYPT_MODE, aeskeySpec); 

    CipherInputStream is = new CipherInputStream(new FileInputStream(in), aesCipher); 
    FileOutputStream os = new FileOutputStream(out); 

    copy(is, os); 

    is.close(); 
    os.close(); 
} 

/** 
* Copies a stream. 
*/ 
private void copy(InputStream is, OutputStream os) throws IOException { 
    int i; 
    byte[] b = new byte[1024]; 
    while((i=is.read(b))!=-1) { 
     os.write(b, 0, i); 
    } 
} 

}

3

錯誤說明了一切:你用128一鍵集初始化和RSA預計至少512

+0

你的教程頁面的底部談論關鍵字長度,我不知道你從哪裏得到128,因爲這在任何地方都沒有提到。 http://www.javamex.com/tutorials/cryptography/rsa_key_length.shtml – 2012-02-01 10:38:22

+0

但是,當我用512給我這個錯誤 異常在線程「主」javax.crypto.IllegalBlockSizeException:數據不能超過64個字節 – 2012-02-01 11:12:46

+0

使用Base64Encoder在加密前對數據進行編碼。 – 2012-02-01 11:26:48

0

你有一個以上的問題:

  1. Java不支持RSA密鑰大小小於512. 2048位是更好的選擇。所以更改密鑰長度:

    kpg.initialize(2048); 
    
  2. String.getBytes()不是逆運算你bytes2String()。加密後,您將字節轉換爲十六進制字符串。但是,在解密之前,將此十六進制字符串轉換爲其ASCII表示形式,這會產生太長的字節數組。相反,使用類似這樣的十六進制字符串轉換回:

    private byte[] string2bytes(String s) { 
        int len = s.length(); 
        byte[] res = new byte[len/2]; 
        for (int i = 0; i < len; i += 2) { 
         res[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 
             + Character.digit(s.charAt(i+1), 16)); 
        } 
        return res; 
    } 
    

    ,然後調用String.getBytes()的,與其:

    // Note, this line is not completely fixed yet 
    String decString = 
        myEncrypt.bytes2String(
        myEncrypt.rsaDecrypt(
         myEncrypt.string2bytes(encString) 
        ) 
    ); 
    
  3. 最後,你有相反的問題。您的bytes2String()方法不會反轉String.getBytes()操作。你加密了「pritesh」.getBytes()的輸出,這就是你從解密操作中得到的結果。現在你必須將它轉換回String。的字符串(字節[]) - 構造函數會爲你做的:

    String decString = 
        new String(
        myEncrypt.rsaDecrypt(
         myEncrypt.string2bytes(encString) 
        ) 
    ); 
    
+0

是的,我改變了你說的話,開始工作,但另一個問題 – 2012-02-02 15:11:32