CDesCBC.java
上传用户:lior1029
上传日期:2013-05-07
资源大小:209k
文件大小:7k
源码类别:

CA认证

开发平台:

Java

  1. package org.infosecurity.cryptography;
  2. /**
  3.  * <p>Title: CBC模式的加密算法 </p>
  4.  * <p>Description: CBC模式的加密算法 </p>
  5.  * <p>Copyright: Copyright (c) 2003</p>
  6.  * <p>Company: 中信信息安全组织(CISO) </p>
  7.  * @author 张荣华 (Eric Zhang)
  8.  * @version 1.0.2003.1022
  9.  */
  10. import org.infosecurity.cryptography.*;
  11. public class CDesCBC extends DES {
  12.     //=========================================================
  13.     // 定义错误类型,以有意义的常量代替数字
  14.     public final static int S_OK        = 1;  /* 成功         */
  15.     public final static int S_IV_ERROR  = -1; /* 初始化向量出错 */
  16.     public final static int S_ENC_ERROR = -2; /* 加密错误      */
  17.     public final static int S_DEC_ERROR = -3; /* 解密错误      */
  18.     /**
  19.      * 构造函数
  20.      * @param pwd 密码 (8 个字节)
  21.      */
  22.     public CDesCBC(byte[] pwd) {
  23.         super(pwd);
  24.     }
  25.     /**
  26.      * CBC模式的加密
  27.      * @param iv  初始向量
  28.      * @param in  输入数据
  29.      * @param out 输出数据
  30.      * @return 输出数据的长度
  31.      */
  32.     public int EncryptCBC(byte[] iv,byte[] in,int in_len,byte[] out)
  33.     {
  34.         // =========================================================
  35.         // 定义变量
  36.         int out_length    = 0;              /* 输出长度           */
  37.         int cur_pos       = 0;              /* 当前位置           */
  38.         int block_count   = 0;              /* 数据块数           */
  39.         byte remaider     = 0;              /* 剩余字节数         */
  40.         byte[] IV         = new byte[8];    /* 初始化向量         */
  41.         byte[] bTemp      = new byte[8];    /* 临时缓冲区         */
  42.         byte[] out_block  = new byte[8];    /* 输出内容           */
  43.         byte[] last_block = new byte[8];    /* 最后一个数据块      */
  44.         // =========================================================
  45.         // 合法性检查
  46.         if(iv == null||iv.length!=8)
  47.             return S_IV_ERROR;
  48.         // =========================================================
  49.         // 处理IV
  50.         out_block = encrypt(iv);
  51.         if(out_block == null || out_block.length == 0)
  52.             return S_ENC_ERROR;
  53.         System.arraycopy(out_block,0,out,0,8);
  54.         System.arraycopy(out_block,0,IV, 0,8);
  55.         out_length += 8;
  56.         cur_pos    += 8;
  57.         // =========================================================
  58.         // 处理输入的数据
  59.         block_count = in_len/8;
  60.         remaider = (byte)(in_len % 8);
  61.         MyDebug.out("输入数据的块数:"+block_count+"t最后一块的字节数:"+remaider);
  62.                                                           /* 调试信息 */
  63.         for(int i = 0 ; i < block_count;i++)
  64.         {
  65.             for(int j = 0;j < 8;j++)
  66.             {
  67.                 IV[j]^=in[8*i+j];
  68.                 MyDebug.out("in["+j+"]="+in[8*i+j]);      /* 调试信息 */
  69.             }
  70.             out_length += 8;
  71.             out_block = encrypt(IV);
  72.             if(out_block == null || out_block.length==0)
  73.                 return S_ENC_ERROR;
  74.             System.arraycopy(out_block,0,out,cur_pos,8);
  75.             System.arraycopy(out_block,0,IV,0,8);
  76.             cur_pos += 8;
  77.             out_block = null;
  78.         }
  79.         // =========================================================
  80.         // 处理输入数据最后一个数据块
  81.         byte value = (byte)(8 - remaider);
  82.         if(remaider > 0)                   /* 如果有数据,将它复制过来 */
  83.             System.arraycopy(in,block_count*8,last_block,0,remaider);
  84.         for(int i = remaider ;i < 8;i++)   /* 进行填充              */
  85.             last_block[i] = value;
  86.         for(int j = 0;j < 8;j++)
  87.             IV[j]^=last_block[j];
  88.         out_length += 8;
  89.         out_block = encrypt(IV);
  90.         if(out_block == null || out_block.length==0)
  91.             return S_ENC_ERROR;
  92.         System.arraycopy(out_block,0,out,cur_pos,8);
  93.         System.arraycopy(out_block,0,IV,0,8);
  94.         return out_length;
  95.     }
  96.     /**
  97.      * CBC模式的解密
  98.      * @param in  输入数据
  99.      * @param out 输出数据
  100.      * @return 输出数据的长度
  101.      */
  102.     public int DecryptCBC(byte[] in,int in_len,byte[] out)
  103.     {
  104.         // =========================================================
  105.         // 定义变量
  106.         int out_length    = 0,cur_pos = 0;  /* 输出长度与当前位置 */
  107.         int block_count   = 0;              /* 数据块数           */
  108.         byte remaider     = 0;              /* 剩余字节数         */
  109.         byte[] IV         = new byte[8];    /* 初始化向量         */
  110.         byte[] bTemp      = new byte[8];    /* 临时缓冲区         */
  111.         byte[] out_block  = new byte[8];    /* 输出内容           */
  112.         byte[] last_block = new byte[8];    /* 最后一个数据块      */
  113.         // =========================================================
  114.         // 处理IV
  115.         System.arraycopy(in,0,IV,0,8);
  116.         // =========================================================
  117.         // 处理输入的数据
  118.         block_count = in_len/8;
  119.         MyDebug.out("输入要解密数据的块数:"+block_count);
  120.         for(int i = 0 ; i < block_count-2;i++) /* -2的原因是要去除第 */
  121.                                                /* 一块和最后一块     */
  122.         {
  123.             System.arraycopy(in,(i+1)*8,bTemp,0,8);
  124.             out_block = decrypt(bTemp);
  125.             if(out_block == null || out_block.length==0)
  126.                 return S_DEC_ERROR;
  127.             for(int j = 0;j < 8;j++)
  128.             {
  129.                 out_block[j]^=IV[j];
  130.                 MyDebug.out("out_block["+j+"]="+out_block[j]);
  131.                                               /* 调试信息          */
  132.             }
  133.             out_length += 8;
  134.             System.arraycopy(out_block,0,out,cur_pos,8);
  135.             System.arraycopy(in,(i+1)*8,IV,0,8);
  136.             cur_pos += 8;
  137.             out_block = null;
  138.         }
  139.         // =========================================================
  140.         // 处理输入数据最后一个数据块
  141.         System.arraycopy(in,(block_count-1)*8,last_block,0,8);
  142.         out_block = decrypt(last_block);
  143.         if(out_block == null || out_block.length==0)
  144.             return S_DEC_ERROR;
  145.         for(int j = 0;j < 8;j++)
  146.         {
  147.             out_block[j]^=IV[j];
  148.             MyDebug.out("last_block["+j+"]="+out_block[j]);
  149.                                              /* 调试信息          */
  150.         }
  151.         byte real_count = (byte)(8 - out_block[7]);
  152.         out_length += real_count;
  153.         if(real_count>0)
  154.             System.arraycopy(out_block,0,out,cur_pos,real_count);
  155.         return out_length;
  156.     }
  157.     /**
  158.      * CBC算法的测试程序
  159.      * @author 张荣华
  160.      * @version 1.0.2003.1027
  161.      */
  162.     public static void main(String[] args) {
  163.         CDesCBC cbc = new CDesCBC("12345678".getBytes());
  164.         byte[] out  = new byte[128];
  165.         byte[] plaintext = new byte[128];
  166.         /* 输入的数据 */
  167.         byte[] in="这一个测试jkdfjkldfjkldfskjlasjkreio978789846r494r9/,.,.m".getBytes();
  168.         byte[] iv="12345678".getBytes();
  169.         System.out.println("明文数据为:"+new String(in));
  170.         /* 加密 */
  171.         int clen = cbc.EncryptCBC(iv,in,in.length,out);
  172.         System.out.println("cipher text len="+clen);
  173.         /* 解密 */
  174.         int plen = cbc.DecryptCBC(out,clen,plaintext);
  175.         byte[] result = new byte[plen];
  176.         System.arraycopy(plaintext,0,result,0,plen);
  177.         System.out.println(new String(result));
  178.     }
  179. }