2011-12-09 54 views
0

我試圖使用非對稱加密在客戶端使用公鑰加密消息並在服務器端使用私鑰解密。不對稱算法的使用問題

解密消息後,它與普拉特文不匹配。你能幫我解決這個問題嗎?

下面是代碼:

import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.math.BigInteger; 
import java.security.InvalidKeyException; 
import java.security.Key; 
import java.security.KeyFactory; 
import java.security.KeyPair; 
import java.security.KeyPairGenerator; 
import java.security.NoSuchAlgorithmException; 
import java.security.PrivateKey; 
import java.security.PublicKey; 
import java.security.spec.InvalidKeySpecException; 
import java.security.spec.RSAPrivateKeySpec; 
import java.security.spec.RSAPublicKeySpec; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 

public class GenerateKeys { 

    public 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(); 
     } 
    } 

    public static void rsaKeyGeneration() { 
     KeyPairGenerator kpg = null; 
     try { 
      kpg = KeyPairGenerator.getInstance("RSA"); 
     } catch (NoSuchAlgorithmException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     kpg.initialize(1024); 
     KeyPair kp = kpg.genKeyPair(); 
     Key publicKey = kp.getPublic(); 
     Key privateKey = kp.getPrivate(); 
     System.out.println("Algo is :" + publicKey.getAlgorithm()); 

     KeyFactory fact = null; 
     try { 
      fact = KeyFactory.getInstance("RSA"); 
     } catch (NoSuchAlgorithmException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     RSAPublicKeySpec pub = null; 
     try { 
      pub = fact.getKeySpec(publicKey, RSAPublicKeySpec.class); 
     } catch (InvalidKeySpecException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     RSAPrivateKeySpec priv = null; 
     try { 
      priv = fact.getKeySpec(privateKey, RSAPrivateKeySpec.class); 
     } catch (InvalidKeySpecException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     try { 
      saveToFile("C:/public1.key", pub.getModulus(), 
        pub.getPublicExponent()); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      saveToFile("C:/private1.key", priv.getModulus(), 
        priv.getPrivateExponent()); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

    PublicKey readKeyFromFile(String keyFileName) throws IOException { 
     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(); 
     } 
    } 

    public byte[] rsaEncrypt(byte[] data) { 
     PublicKey pubKey = null; 
     try { 
      pubKey = readKeyFromFile("C:/public1.key"); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     Cipher cipher = null; 
     try { 
      cipher = Cipher.getInstance("RSA"); 
     } catch (NoSuchAlgorithmException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (NoSuchPaddingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      cipher.init(Cipher.ENCRYPT_MODE, pubKey); 
     } catch (InvalidKeyException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     byte[] cipherData = null; 
     try { 
      cipherData = cipher.doFinal(data); 
     } catch (IllegalBlockSizeException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (BadPaddingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     System.out 
       .println("encrypted card number is :" + cipherData.toString()); 
     return cipherData; 
    } 

    PrivateKey readPriKeyFromFile(String keyFileName) throws IOException { 
     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 pKey = fact.generatePrivate(keySpec); 
      return pKey; 
     } catch (Exception e) { 
      throw new RuntimeException("Spurious serialisation error", e); 
     } finally { 
      oin.close(); 
     } 
    } 

    public byte[] rsaDecrypt(byte[] sampleText) { 
     PrivateKey priKey = null; 
     try { 
      priKey = readPriKeyFromFile("C:/private1.key"); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     Cipher cipher = null; 
     try { 
      cipher = Cipher.getInstance("RSA"); 
     } catch (NoSuchAlgorithmException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (NoSuchPaddingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      cipher.init(Cipher.DECRYPT_MODE, priKey); 
     } catch (InvalidKeyException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     byte[] cipherData = null; 
     try { 
      cipherData = cipher.doFinal(sampleText); 
      // cipherData = cipher. 
     } catch (IllegalBlockSizeException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (BadPaddingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return cipherData; 
    } 

    public static void main(String s[]) { 
     System.out 
       .println("++++++++++++++++++++ Program to create the Keys+++++++++++++++++++++++++++++"); 
     rsaKeyGeneration(); 
     String sText = "HRB"; 
     System.out.println("Plain Text Card Number :" + sText); 
     GenerateKeys keys = new GenerateKeys(); 
     byte[] encryptedCardNo = keys.rsaEncrypt(sText.getBytes()); 
     byte[] decryptedCardNo = keys.rsaDecrypt(encryptedCardNo); 
     System.out.println("Decrypted card number is :" 
       + decryptedCardNo.toString()); 

    } 
} 
+0

你有一些技巧在這裏了,請把它標記爲關閉。 – amrfaissal

回答

1

,由於您使用的是toString()方法,它返回一個可怕的表現是正常的。所以你應該使用十六進制表示來顯示加密和解密的文本。下面是做這項工作的函數:

public String byteArrayToHexString(byte[] bArray){ 
    StringBuffer buffer = new StringBuffer(); 

    for(byte b : bArray) { 
     buffer.append(Integer.toHexString(b)); 
     buffer.append(" "); 
    } 

    return buffer.toString();  
} 
1

使用String.getBytes(字符集):字節[]和新的字符串(字節[],字符集):String方法代替的toString()。 toString()只會給你對字節數組的引用。作爲字符集,使用Charset.forName(「UTF-8」),它總是受任何Java兼容平臺(以及Apache Harmony的支持)。

private static final Charset UTF8 = Charset.forName("UTF-8"); 

...

System.out.println(new String("Hi there!".getBytes(UTF8), UTF8)); 
+1

然而,在任何情況下,您都不應該嘗試從加密產生的字節數組中構造一個String實例。每個Charset只支持所有可能代碼的一個子集,但密碼輸出可以是完全任意的。 –

+0

感謝GregS的加入。這是關於顯示解密的數據,所以我沒有提到它。 –