Perl和Java之间的blowfish加密的区别

时间:2015-06-29 21:13:13

标签: java perl encryption blowfish

我们在Java和Perl中编写和应用程序将加密的CBC Blowfish存储在同一个数据库中。两者都将加密和解密,因此他们需要能够获得另一个加密的纯文本。

a)我去了一些在线工具用CBC和IV矢量加密一些文本。一个这样的网站is this
明文HELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOU 关键1234567890
由于该网站不允许输入IV矢量,我们假设它将归零,结果证明是正确的:

密文
P4mtWDzIIc2x / Taqc9T46A3T0aTCelmANBRf6RgEzSF29DLdMRiEhck98jac04 + Tg0q7HpLalow0J6nZNUW + HWtRvYmLnt92UuIZ1ckaBEa9TSdR2YP9rQ ==

b)以下Java代码执行加密:

import java.security.InvalidAlgorithmParameterException;  
import java.security.InvalidKeyException;  
import java.security.NoSuchAlgorithmException;  

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.*;

import org.apache.commons.codec.binary.*;

public class simple {

 public static void main(String[] args) {
   String Key = "1234567890";
   byte[] KeyData = Key.getBytes(); 
   String IV    = "\0\0\0\0\0\0\0\0";

   try { 
     SecretKeySpec KS = new SecretKeySpec(KeyData, "Blowfish");
     // modo CBC
     Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
     try {
       try {    
         IvParameterSpec IVparam = new javax.crypto.spec.IvParameterSpec(IV.getBytes());                     
         cipher.init(Cipher.ENCRYPT_MODE, KS,IVparam);
       } catch (InvalidAlgorithmParameterException e) {System.out.println(e);};  
     } catch (InvalidKeyException e) {System.out.println(e);};  

    // get the text to encrypt
    String inputText = "HELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOU";

    // encrypt message
    try {
      byte[] encrypted = cipher.doFinal(inputText.getBytes());
      Base64 b64 = new Base64();
      System.out.println("Java Ciphertext\n" + b64.encodeAsString(encrypted));
    } catch (IllegalBlockSizeException e) {System.out.println(e);}
    catch (BadPaddingException e) {System.out.println(e);}  
   }  
   catch (NoSuchPaddingException e) {}
   catch (NoSuchAlgorithmException e) {}
 }   

}

输出结果为:
Java Ciphertext
P4mtWDzIIc2x / Taqc9T46A3T0aTCelmANBRf6RgEzSF29DLdMRiEhck98jac04 + Tg0q7HpLalow0J6nZNUW + HWtRvYmLnt92UuIZ1ckaBEaLkpDfHZfp8g ==

正如你可以看到两个输出“几乎”相同(可能是由于填充,但目前没有相关性。但是很奇怪,因为明文是故意80个​​字符以避免填充)

c)我们写了这个小的Perl程序:

#!/usr/bin/perl -w
use strict;
use Crypt::Blowfish;
use MIME::Base64;
use Crypt::CBC;

my $cipher = Crypt::CBC->new(-key => "1234567890\0\0\0\0\0\0", -cipher => "Blowfish", -iv => "\0\0\0\0\0\0\0\0", -literal_key => 1, -header => "none", -keysize => 16);
my $ciphertext = $cipher->encrypt("HELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOU");

print "Perl Base64: ",encode_base64($ciphertext),"\n"; 
print "Descrifrado: ", $cipher->decrypt($ciphertext); 

但是这个程序产生以下内容:
Perl Base64: AW0AYJfIp1Lg5L + zTM0nZj07U6ETlxxIg3CKiZItg8wkA1Jqx79ZckzWfYwzN26ZPyCDnlfh0b37 0ZK61ng8MaMc9RFgtuXTeYLBOJC7LGYCHlMddmPwUQ ==
Descrifrado: HELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOU

这与Java程序(与在线工具一致)不同,尽管它可以正确获取纯文本

所以也许我们没有在对象创建中提示相同的参数。特别是:

my $cipher = Crypt::CBC->new(-key => "1234567890\0\0\0\0\0\0", -cipher => "Blowfish", -iv => "\0\0\0\0\0\0\0\0", -literal_key => 1, -header => "none", -keysize => 16);

在检查代码之后,我唯一的猜测是Java和Perl使用不同的密钥大小,所以我的问题是

¿Java使用的密钥大小是多少?浏览 SecretKeySpec here的源代码后,我们无法确定这样的大小,因此假定为128位,因此16位大小(16 x 8 = 128)和键的\ 0填充在Perl代码中。

当然,如果你能发现别的错误,我们将不胜感激。

1 个答案:

答案 0 :(得分:4)

在Java中,您使用

String Key = "1234567890";

在Perl中,您使用

my $key = "1234567890\0\0\0\0\0\0";

如果您实际使用了相同的密钥,则会得到相同的结果。

my $key = "1234567890";

-literal_key => 1, -key => $key, -keysize => length($key)