[原创]Java实现PKCS7填充的DES加密(修订版)

      在一个项目中,要求C#和Java交互,为了保障数据的安全传输,我们用到DES加密。
在DES加密中,要求指定Key,IV,CipherMode(CBC),PaddingMode。Key和IV,CipherMode都好说,只是PaddingMode不好指定,因为C#的模式有:ANSIX923、ISO10126、None、PKCS7、Zero,而Java有:OAEPWith<digest>And<mgf>Padding、PKCS5Padding、SSL3Padding,没有交集呀。
      我用C#先写出来的,PaddingMode = PKCS7,Java方的不好作了。没有办法,只好帮人家写一个Java的例子,于是有了下面的代码:(Java高手不要笑话呀)

import java.io.*
import java.security.spec.*
import javax.crypto.*
import javax.crypto.spec.*

import sun.misc.BASE64Encoder;
  
    
/*
    作者:阿牛(牛昆亮) QQ:273352165 MSN:niukl@hotmail.com
    
    声明:可以免费使用,请您保留此信息
        如果您有什么改过,记得告诉我!
    
*/


     
public class DesPKCS7Encrypter 
         Cipher ecipher; 
         Cipher dcipher;
         
         DesPKCS7Encrypter(
byte[] keyBytes, byte[] ivBytes)
             
throws Exception
         
{
              Init(keyBytes,ivBytes);
         }

       
         
         DesPKCS7Encrypter(DESKeySpec keySpec, IvParameterSpec ivSpec)
            
throws Exception             
         
{
             Init(keySpec,ivSpec);
         }

          
private void Init(byte[] keyBytes, byte[] ivBytes)
             
throws Exception
         
{
             DESKeySpec dks 
= new DESKeySpec(keyBytes);
             SecretKeyFactory keyFactory 
= SecretKeyFactory.getInstance( "DES" );
             SecretKey key 
= keyFactory.generateSecret( dks );
             IvParameterSpec iv 
= new IvParameterSpec(ivBytes);
             Init(key,iv);
             
         }

         
         
private void Init(DESKeySpec keySpec, IvParameterSpec iv)
             
throws Exception
         
{
                SecretKeyFactory keyFactory 
= SecretKeyFactory.getInstance( "DES" );
             SecretKey key 
= keyFactory.generateSecret( keySpec );
             Init(key,iv);
        }

         
         
private void Init(SecretKey key, IvParameterSpec iv)
             
throws Exception
         
{
             AlgorithmParameterSpec paramSpec 
= iv; 
             
try 
                 ecipher 
= Cipher.getInstance("DES/CBC/NoPadding"); 
                 dcipher 
= Cipher.getInstance("DES/CBC/NoPadding"); 
  
                 
// CBC requires an initialization vector 
                 ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); 
                 dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec); 
             }

             
catch (Exception e) 
                 
throw e;
             }

            
         }

  
  
         
public void encrypt(InputStream in, OutputStream out) 
             
try 
                 
// Bytes written to out will be encrypted 
                 out = new CipherOutputStream(out, ecipher); 
                 
byte[] buf = new byte[this.ecipher.getBlockSize()];
  
                 
// Read in the cleartext bytes and write to out to encrypt 
                 int numRead = 0;
                 
while (true)
                 
{
                     numRead 
= in.read(buf);
                     
boolean bBreak = false;
                     
if(numRead == -1 || numRead < buf.length)
                      
{
                         
int pos = numRead == -1? 0:numRead;
                         
byte byteFill = (byte)(buf.length - pos);
                         
for(int i = pos;i<buf.length; ++i)
                         
{
                             buf[i] 
= byteFill;
                         }

                         bBreak 
= true;
                     }

                     out.write(buf);
                     
                     
if(bBreak)
                         
break;
                }
 
                out.close(); 
             }
 catch (java.io.IOException e) 
                 System.out.println(
"Exception e in encrypt="+e); 
             }
 
         }
 
  
         
public void decrypt(InputStream in, OutputStream out) 
             
try 
                 
// Bytes read from in will be decrypted 
                 in = new CipherInputStream(in, dcipher); 
                 
byte[] buf = new byte[this.dcipher.getBlockSize()];
                  
                 
// Read in the decrypted bytes and write the cleartext to out 
                 int numRead = 0
                 
while ((numRead = in.read(buf)) >= 0
                     
if(in.available() > 0)
                     
{
                         out.write(buf, 
0, numRead);                          
                     }

                     
else
                     
{
                         
byte byteBlock = buf[buf.length -1];
                         
int i = 0;
                         
for(i = buf.length - byteBlock; i >= 0 && i < buf.length; ++i)
                         
{
                             
if(buf[i] != byteBlock)
                             
{
                                 
break;
                             }

                         }

                         
                         
if(i == buf.length)
                         
{
                            out.write(buf,
0,buf.length - byteBlock); 
                         }

                         
else
                         
{
                             out.write(buf);
                         }

                     }

                 }

                 
                 out.close(); 
             }
 catch (java.io.IOException e) 
                 System.out.println(
"Exception e in decrypt="+e); 
             }
 
         }
 
         
         
public static void main(String args[]) 
         

             
try 
             

                 
// 生成Key和IV
                 byte[] byteKey = new byte[8]; //"12345678".getBytes("ASCII");
                 byte[] byteIv =  new byte[8]; //"98765432".getBytes("ASCII");
                 FileInputStream fisKey = new FileInputStream("key.dat");
                 FileInputStream fisIv 
= new FileInputStream("iv.dat");
                 fisKey.read(byteKey);
                 fisIv.read(byteIv);
                 fisKey.close();
                 fisIv.close();
                 
                 
// 创建加密实例 
                 DesPKCS7Encrypter encrypter = new DesPKCS7Encrypter(byteKey,byteIv); 
                 
// 生成要加密的数据 
                 String strData = "ni hao";
                 System.out.println(strData);
                 ByteArrayInputStream bais 
= new ByteArrayInputStream(strData.getBytes("utf-8"));
                 
// 声明加密输出
                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 
// Base64 加密实例
                 BASE64Encoder base64Encoder = new BASE64Encoder();
                 
                 
//加密
                 encrypter.encrypt(bais,baos); 
                 
                 
//Base64加密
                 String outStr = base64Encoder.encode(baos.toByteArray());
                 
//结果
                 System.out.println(outStr);
                 
                 
// 初始化解密数据
                 bais = new ByteArrayInputStream(baos.toByteArray());
                 
// 声明解密输出
                 baos = new ByteArrayOutputStream();
                 
// 解密 
                 encrypter.decrypt(bais,baos); 
                 
//查看解密结果
                 System.out.println(baos.toString("utf-8")); 
                 
           }
 catch (Exception e) 
             System.out.println(
"Exception e="+e); 
           }

        }
 
     }
 

      也许还有更好的方法,也许Java已经有了该方法。还请高手告诉我呀。

QQ:273352165 evlon#126.com 转载请注明出处。
原文地址:https://www.cnblogs.com/evlon/p/374971.html