惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Project Zero
Project Zero
N
Netflix TechBlog - Medium
P
Privacy International News Feed
Cisco Talos Blog
Cisco Talos Blog
Recorded Future
Recorded Future
C
Cybersecurity and Infrastructure Security Agency CISA
The Register - Security
The Register - Security
P
Palo Alto Networks Blog
GbyAI
GbyAI
量子位
Simon Willison's Weblog
Simon Willison's Weblog
Cyberwarzone
Cyberwarzone
M
MIT News - Artificial intelligence
T
Threatpost
腾讯CDC
MyScale Blog
MyScale Blog
P
Privacy & Cybersecurity Law Blog
罗磊的独立博客
博客园 - 叶小钗
V
V2EX
美团技术团队
NISL@THU
NISL@THU
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
C
Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
Google Online Security Blog
Google Online Security Blog
PCI Perspectives
PCI Perspectives
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
爱范儿
爱范儿
G
Google Developers Blog
博客园 - Franky
P
Proofpoint News Feed
T
The Blog of Author Tim Ferriss
B
Blog
Spread Privacy
Spread Privacy
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Latest news
Latest news
The GitHub Blog
The GitHub Blog
T
Threat Research - Cisco Blogs
D
DataBreaches.Net
F
Full Disclosure
L
LINUX DO - 热门话题
Stack Overflow Blog
Stack Overflow Blog
Scott Helme
Scott Helme
C
CERT Recently Published Vulnerability Notes
Jina AI
Jina AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Fortinet All Blogs

博客园 - 爱东东

解决SQLServer2005孤立用户问题 RJ45做法 win下安装MRTG MySQL和SQLServer互转 AspNetUrl重写2级域名 解决XP安装了SP3后无法安装更新补丁的方法 QQ代码 工作流例子 关于推广网络游戏《传奇3》计划书 几个很受启发的创意营销经典 软件开发人员创业做什么方向好?自己的疑问! ascentSVN地址备忘 ascent服务器架设新手教程 魔兽世界GM技能表 MySQL获取首字母拼音方法 解决win2003下delphi出现内存读写错误 魔兽世界高法伤技能列表 汇编算术运算指令 8088 汇编速查手册
Java.net3DES差异及互通
爱东东 · 2009-01-07 · via 博客园 - 爱东东

主要差异如下:

1、  对于待加密解密的数据,各自的填充模式不一样

      C#的模式有:ANSIX923、ISO10126、None、PKCS7、Zero,而Java有:NoPadding、PKCS5Padding、SSL3Padding

2、  各自默认的3DES实现,模式和填充方式不一样

C#的默认模式为CBC,默认填充方式为PKCS7; java的默认模式为ECB,默认填充方式为PKCS5Padding

3、  各自的key的size不一样

C#中key的size为16和24均可;java中要求key的size必须为24;对于CBC模式下的向量iv的size两者均要求必须为8

翻看了3DES的原理:

DES主要采用替换和移位的方法,用56位密钥对64位二进制数据块进行加密,每次加密可对64位的输入数据进行16轮编码,

经一系列替换和移位后,输入的64位转换成安全不同的64的输出数据

.  
3DES:是在DES的基础上采用三重DES,即用两个56位的密钥K1,K2,发送方用K1加密,K2解密,再使用K1加密.接收方使用K1解密,K2加密,再使用K1解密,

其效果相当于密钥长度加倍.

于是尝试在java中,对key进行补位,即用前8个字节作为byte[24] 中的byte[16]~byte[23];发现与c#中加密的结果相同!于是大胆假设C#中可能是检查key的size为16的时候

自动将前8个字节作为k3进行了补位,而java没有实现这一点(因为java的3DES算法中强制要求key的size必须为24)。这样的情况下,可能就是发送方用k1加密、k2解密、k3再加密;接受方k3解密、k2加密、再k1解密来实现。

最终经过编码验证,确认key大小为24时,java和c#的加密解密结果相一致。

Java中实现时,只要注意对大小不足24的key进行补位,和采用CBC模式,填充模式为PKCS5Padding即可。

C#中的实现:

    public void test()

        {

            SymmetricAlgorithm des = new TripleDESCryptoServiceProvider();

            des.Key = Encoding.UTF8.GetBytes("wserrtyuiop12fer");

            des.IV = Encoding.UTF8.GetBytes("12345678");

            string str = "test";

            byte[] byt = Encoding.UTF8.GetBytes(str);

            MemoryStream ms = new MemoryStream();

            ICryptoTransform ct = mCSP.CreateEncryptor(des.Key, des.IV);

            CryptoStream  cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);

            cs.Write(byt, 0, byt.Length);

            cs.FlushFinalBlock();

            cs.Close();

            string enctext64=Convert.ToBase64String(ms.ToArray());

            Console.Out.WriteLine("enctext64: {0}", enctext64);

        }

Java中的实现:

public static void main(String[] args) {

       try {

           byte[] key = "wserrtyuiop12fercsffswqh".getBytes();

           byte[] iv = "12345678".getBytes();

           String s = "test";

           s="9EC610E687CA2642147F3BB1779E1C56:820124";          

           BASE64Decoder base64decoder = new BASE64Decoder();

           BASE64Encoder base64encoder = new BASE64Encoder();

           iv = base64decoder.decodeBuffer("H06BDKgg/kI=");

           byte[] bt = base64decoder.decodeBuffer("nsYQ5ofKJkIUfzuxd54cVg==");

           System.out.println("original key size:" + bt.length);

           byte[] kbt = new byte[bt.length + 8];

           System.arraycopy(bt, 0, kbt, 0, bt.length);

           System.arraycopy(bt, 0, kbt, 16, 8);

           System.out.println("key base64: " + base64encoder.encode(kbt));

           key=kbt;

           System.out.println("key size:" + key.length);

           String result = encryptWithIV(key, iv, s);

           System.out.println("encrypt result: " + result);

       } catch (Exception e) {

           e.printStackTrace();

       }

    }

    public static String encryptWithIV(byte[] key, byte[] iv, String str) throws Exception {

       SecureRandom sr = new SecureRandom();

       DESedeKeySpec dks = new DESedeKeySpec(key);

       SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");

       SecretKey securekey = keyFactory.generateSecret(dks);

       IvParameterSpec ips = new IvParameterSpec(iv);

       Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");

       cipher.init(Cipher.ENCRYPT_MODE, securekey, ips, sr);

       byte[] bt = cipher.doFinal(str.getBytes("utf-8"));

       System.out.println("encrypt base64: " + new BASE64Encoder().encode(bt));

       return new String(Hex.encodeHex(bt));

    }

还有一种让Java和.Net兼容的方式,在.Net中指定模式为ECB,填充为PKCS7,然后在Java中采用其默认的模式(DESede/ECB/PKCS5Padding)即可,注意双方约定key的size为24个字节。建议双方对key以base64编码字符串进行告知,因为java和.net中byte字节的范围不相同(前者-128~127,后者0~255),避免不必要的处理。

摘自 http://gaoge2000.blog.hexun.com/18731819_d.html