Rabbit流密码的Java实现
2009-09-25 03:36
99 查看
1. Rabbit流密码(Rabbit Stream Cipher)简介
Rabbit流密码是由Cryptico公司(http://www.cryptico.com)设计的,密钥长度128位,
最大加密消息长度为264 Bytes,即16 TB,若消息超过该长度,则需要更换密钥对剩下的消息进行处理。它是目前安全性较高,加/解密速度比较高效的流密码之一,在各种处理器平台上都有不凡的表现。
详细资料:
1.http://www.cryptico.com/Files/filer/rabbit_fse.pdf
2.http://www.ietf.org/rfc/rfc4503.txt
本文实现了该算法的java语言实现,仅供参考。
Rabbit流密码的C/C++实现请参考我的加密算法库CryptoFBC: code.google.com/p/cryptofbc
2. 实现源码
Rabbit流密码是由Cryptico公司(http://www.cryptico.com)设计的,密钥长度128位,
最大加密消息长度为264 Bytes,即16 TB,若消息超过该长度,则需要更换密钥对剩下的消息进行处理。它是目前安全性较高,加/解密速度比较高效的流密码之一,在各种处理器平台上都有不凡的表现。
详细资料:
1.http://www.cryptico.com/Files/filer/rabbit_fse.pdf
2.http://www.ietf.org/rfc/rfc4503.txt
本文实现了该算法的java语言实现,仅供参考。
Rabbit流密码的C/C++实现请参考我的加密算法库CryptoFBC: code.google.com/p/cryptofbc
2. 实现源码
/** * The Java Implementation of Rabbit Stream Cipher * @author cnbragon * @email cnbragon_dot_163_dot_com * @date 2009/09/25 * @note Not implemented IV scheme * @Reference: * 1.http://www.cryptico.com/Files/filer/rabbit_fse.pdf * 2.http://www.ietf.org/rfc/rfc4503.txt */ class Rabbit { private int[] x = new int[8]; private int[] c = new int[8]; private int carry; public void Rabbit() { for(int i = 0; i < 8; i++) { x[i] = c[i] = 0; } carry = 0; } private int g_func(int x) { int a = x & 0xffff; int b = x >>> 16; int h =( ( ( ( a * a ) >>> 17 ) + ( a * b ) ) >>> 15 ) + b * b; int l = x * x; return h ^ l; } /** * @declaration 比较两个有符号整数的十六进制的大小,即作为无符号整数进行比较 * @param x * @param y * @return 若(unsigned x) < (unsigned y),则返回1,否则返回0 */ private int compare(int x, int y) { long a = x; long b = y; a &= 0x00000000ffffffffl; b &= 0x00000000ffffffffl; return (a < b) ? 1 : 0; } private int rotL(int x, int y) { return ( x << y ) | ( x >>> (32 - y) ); } private void next_state() { int[] g = new int[8]; int[] c_old = new int[8]; int i = 0; for( i = 0; i < 8; i++) { c_old[i] = c[i]; } c[0] += 0x4d34d34d + carry; c[1] += 0xd34d34d3 + compare(c[0], c_old[0]); c[2] += 0x34d34d34 + compare(c[1], c_old[1]); c[3] += 0x4d34d34d + compare(c[2], c_old[2]); c[4] += 0xd34d34d3 + compare(c[3], c_old[3]); c[5] += 0x34d34d34 + compare(c[4], c_old[4]); c[6] += 0x4d34d34d + compare(c[5], c_old[5]); c[7] += 0xd34d34d3 + compare(c[6], c_old[6]); carry = compare(c[7], c_old[7]); for( i = 0; i < 8; i++) { g[i] = g_func(x[i] + c[i]); } x[0] = g[0] + rotL(g[7], 16) + rotL(g[6], 16); x[1] = g[1] + rotL(g[0], 8 ) + g[7]; x[2] = g[2] + rotL(g[1], 16) + rotL(g[0], 16); x[3] = g[3] + rotL(g[2], 8 ) + g[1]; x[4] = g[4] + rotL(g[3], 16) + rotL(g[2], 16); x[5] = g[5] + rotL(g[4], 8 ) + g[3]; x[6] = g[6] + rotL(g[5], 16) + rotL(g[4], 16); x[7] = g[7] + rotL(g[6], 8 ) + g[5]; } /** * @declaration 将一个字节数组转化为整数,采用Big-Endian格式进行解析 * @param a 待转化的字节数组 * @param i 字节数组的起始索引 * @return 转化后的整数 */ public static int os2ip(byte[] a, int i) { int x0 = a[i + 3] & 0x000000ff; int x1 = a[i + 2] << 8 & 0x0000ff00; int x2 = a[i + 1] << 16 & 0x00ff0000; int x3 = a[i] << 24 & 0xff000000; return x0 | x1 | x2 | x3; } /** * @declaration 将整数x转化为4字节数组,采用Big-Endian格式进行解析 * @param x 待转化的整数x * @return 解析后的字节数组,长度为4 */ public static byte[] i2osp(int x) { byte[] s = new byte[4]; s[3] = (byte)( x & 0x000000ff ); s[2] = (byte)( ( x & 0x0000ff00 ) >>> 8 ); s[1] = (byte)( ( x & 0x00ff0000 ) >>> 16 ); s[0] = (byte)( ( x & 0xff000000 ) >>> 24 ); return s; } /** * @declaration 密钥初始化函数 * @param p_key 长度为128位的密钥数组,若密钥长度小于128位, * 则必须在填充后再调用该函数 */ public void keySetup(byte[] p_key) { int k0, k1, k2, k3, i; k0 = os2ip(p_key, 12); k1 = os2ip(p_key, 8); k2 = os2ip(p_key, 4); k3 = os2ip(p_key, 0); x[0] = k0; x[2] = k1; x[4] = k2; x[6] = k3; x[1] = ( k3 << 16 ) | ( k2 >>> 16 ); x[3] = ( k0 << 16 ) | ( k3 >>> 16 ); x[5] = ( k1 << 16 ) | ( k0 >>> 16 ); x[7] = ( k2 << 16 ) | ( k1 >>> 16 ); c[0] = rotL(k2, 16); c[2] = rotL(k3, 16); c[4] = rotL(k0, 16); c[6] = rotL(k1, 16); c[1] = (k0 & 0xffff0000) | (k1 & 0x0000ffff); c[3] = (k1 & 0xffff0000) | (k2 & 0x0000ffff); c[5] = (k2 & 0xffff0000) | (k3 & 0x0000ffff); c[7] = (k3 & 0xffff0000) | (k0 & 0x0000ffff); carry = 0; for( i = 0; i < 4; i++) { next_state(); } for( i = 0; i < 8; i++) { c[ (i + 4) & 7 ] ^= x[i]; } } /** * @declaration 该函数用于生成128位随机密钥,用于直接和明文进行异或处理 * @param p_dest 产生的128位随机密钥 * @param data_size 需要产生的随机密钥数量,必须是16的倍数 */ public void getS(byte[] p_dest, long data_size) { int i, j, m; int[] k = new int[4]; byte[] t = new byte[4]; for( i = 0; i < data_size; i+=16) { next_state(); k[0] = x[0] ^ ( x[5] >>> 16 ) ^ ( x[3] << 16 ); k[1] = x[2] ^ ( x[7] >>> 16 ) ^ ( x[5] << 16 ); k[2] = x[4] ^ ( x[1] >>> 16 ) ^ ( x[7] << 16 ); k[3] = x[6] ^ ( x[3] >>> 16 ) ^ ( x[1] << 16 ); for( j = 0; j < 4; j++) { t = i2osp(k[j]); for( m = 0; m < 4; m++) { p_dest[ j * 4 + m ] = t[m]; } } } } /** * @declaration 加密和解密函数 * @param p_src 需要加密或解密的消息,其长度必须是16的倍数,以字节为单位, * 若不是16的倍数,则需要在调用该函数前进行填充,一般填充值 * 为0的字节 * @param p_dest 加密或解密的结果,其长度必须是16的倍数,以字节为单位 * 并且长度必须大于等于p_src的长度 * @param data_size 需要处理的消息的长度,必须是16的倍数,以字节为单位 * 其值为p_src的长度 */ public void cipher(byte[] p_src, byte[] p_dest, long data_size) { int i, j, m; int[] k = new int[4]; byte[] t = new byte[4]; for( i = 0; i < data_size; i+=16) { next_state(); k[0] = os2ip(p_src, i * 16 + 0) ^ x[0] ^ ( x[5] >>> 16 ) ^ ( x[3] << 16 ); k[1] = os2ip(p_src, i * 16 + 4) ^ x[2] ^ ( x[7] >>> 16 ) ^ ( x[5] << 16 ); k[2] = os2ip(p_src, i * 16 + 8) ^ x[4] ^ ( x[1] >>> 16 ) ^ ( x[7] << 16 ); k[3] = os2ip(p_src, i * 16 + 12) ^ x[6] ^ ( x[3] >>> 16 ) ^ ( x[1] << 16 ); for( j = 0; j < 4; j++) { t = i2osp(k[j]); for( m = 0; m < 4; m++) { p_dest[ i * 16 + j * 4 + m ] = t[m]; } } } } } public class Main { public static void main(String[] args) { /** * 定义测试密钥key,需要注意的是,由于java没有unsigned类型, * 所以需要对大于等于0x80的字节进行类型转换, * 比较方便的办法是都加上(byte) */ byte[] key = { (byte)0xa0, (byte)0x33, (byte)0xd6, (byte)0x78, (byte)0x6b, (byte)0x05, (byte)0x14, (byte)0xac, (byte)0xfc, (byte)0x3d, (byte)0x8e, (byte)0x2d, (byte)0x6a, (byte)0x2c, (byte)0x27, (byte)0x1d }; /** * 定义待加密的消息message,密文ciphertext,并初始化为0 */ byte[] message = new byte[16]; byte[] ciphertext = new byte[16]; for( int i = 0; i < 16; i++) { message[i] = (byte)i; ciphertext[i] = 0; } /** * 调用Rabbit流密码进行加密 */ Rabbit rtest = new Rabbit(); /* * 初始化密钥 */ rtest.keySetup(key); /* * 加密 */ rtest.cipher(message, ciphertext, 16); for( int i = 0; i < 16; i++) { System.out.printf("%02x ", ciphertext[i]); } System.out.println(); /** * 调用Rabbit流密码进行解密 */ Rabbit rtest2 = new Rabbit(); /* * 初始化密钥 */ rtest2.keySetup(key); byte[] szT = new byte[16]; for( int i = 0; i < 16; i++) { szT[i] = 0; } /* * 解密 */ rtest2.cipher(ciphertext, szT, 16); for( int i = 0; i < 16; i++) { System.out.printf("%02x ", szT[i]); } System.out.println(); } }
相关文章推荐
- Rabbit流密码的Java实现
- Json字符串转换为java对象的各种实现方法【json_lib框架、Gson、org.json】
- Java多线程实现的2个方式
- 两个有序单链表合并成一个有序单链表的java实现
- java实现文件的上传和下载
- Java实现排序算法之堆排序
- Java 操作 Excel (读取Excel2007,Poi实现)
- 用JAVA实现MSNMessager的功能
- Java的MD5实现
- 谁能帮我做一个用JAVA来实现的FTP服务器??速回!!
- java中分页效果的实现代码
- java实现的KMP算法
- 设计模式(Design Pattern) - 行为型模式(Behavioral Pattern) - 解释器模式(Interpreter) - Java实现
- cocos2dx 使用jni实现java调用c++
- java中多线程模拟(多生产,多消费,Lock实现同步锁,替代synchronized同步代码块)
- Java线程实现
- 剑指offer----旋转数组的最小数字----java实现
- Java怎么实现多继承的功效
- 基于Java的三重DES算法实现
- Java调用DOS命令实现关机