RSA加密Socket传输文件、签名(一)

RSA加密分为公钥加密和私钥解密以及可能的数字签名。

公钥、私钥分居客户端和服务器端,分别用于加密和解密。同时,私钥还用于签名,公钥还用于验证签名。

解密加密用到JDK中java.security、javax.crypto两个包中相关的接口和类

 

1.生成密钥的代码

 

  1. SecureRandom sr = new SecureRandom();  
  2.             KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");  
  3.             // 注意密钥大小最好为1024,否则解密会有乱码情况.   
  4.             kg.initialize(1024, sr);  
  5.             KeyPair kp = kg.generateKeyPair();  
  6.               
  7.             String privateKeyName = keyFile.substring(0,keyFile.lastIndexOf("."))+"_private"+keyFile.substring(keyFile.lastIndexOf("."));  
  8.             String publicKeyName = keyFile.substring(0,keyFile.lastIndexOf("."))+"_public"+keyFile.substring(keyFile.lastIndexOf("."));  
  9.             FileOutputStream fos = new FileOutputStream(privateKeyName);  
  10.             ObjectOutputStream oos = new ObjectOutputStream(fos);  
  11.             // 生成私钥   
  12.             oos.writeObject(kp.getPrivate());  
  13.             oos.close();  
  14.               
  15.             //生成公钥   
  16.             fos = new FileOutputStream(publicKeyName);  
  17.             oos = new ObjectOutputStream(fos);  
  18.             oos.writeObject(kp.getPublic());  
  19.             oos.close();  

 

 

 

2.加密、解密(RSA加密速度比较慢,原因是每次只能为最多117 bytes加密,加密之后为128 Bytes)

 

  1. //加密   
  2. Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");  
  3. cipher.init(Cipher.ENCRYPT_MODE, (PublicKey)getKey(keyFile,"public"));  
  4. return cipher.doFinal(text);  
  5. //加密   
  6. Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");  
  7. cipher.init(Cipher.DECRYPT_MODE, (PrivateKey)getKey(keyFile,"private"));  
  8. return cipher.doFinal(text);  

 

 

 

3.用私钥进行数字签名,用于服务器端验证客户端数据是否是正确数据。

 

  1.        public byte[] getSignature(byte[] cipherText){  
  2.     try {  
  3.         coder = new RSASecurityCoder();  
  4.         Signature sig = Signature.getInstance("SHA1withRSA");  
  5.         PrivateKey privateKey = (PrivateKey)coder.getKey(this.key, "private");  
  6.         sig.initSign(privateKey);  
  7.         sig.update(cipherText);  
  8.         return sig.sign();  
  9.     } catch (Exception e) {  
  10.         e.printStackTrace();  
  11.     }  
  12.     return null;  
  13. }  
  14.   
  15. public boolean verifySignature(byte[] cipherText,byte[] signature){  
  16.     try {  
  17.         coder = new RSASecurityCoder();  
  18.         Signature sig = Signature.getInstance("SHA1withRSA");  
  19.         PublicKey publicKey = (PublicKey)coder.getKey(this.key, "public");  
  20.         sig.initVerify(publicKey);  
  21.         sig.update(cipherText);  
  22.         return sig.verify(signature);  
  23.     } catch (Exception e) {  
  24.         e.printStackTrace();  
  25.     }  
  26.     return false;  
  27. }  

 

 

 

数字签名是在客户端进行,所用的私钥不是和用于加密的公钥成对的。

也就是说这样的通信 要在客户端保存有 服务器端的公钥和本地的私钥,而服务器端应该保存有本地的私钥和客户端的公钥。

你可能感兴趣的:(java,多线程,thread,加密解密)