Perl 和 Java 之间河豚加密的差异
Difference in blowfish encryption between Perl and Java
我们在 Java 和 Perl 中编写和应用程序,将加密的 CBC Blowfish 存储在同一个数据库中。双方都将加密和解密,因此他们需要能够获得对方加密的纯文本。
a) 我使用一些在线工具用 CBC 和 IV 向量加密了一些文本。一个这样的网站 is this
明文你好你好你好你好你好你好你好你好你好你好你好你好你好
钥匙 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 = "[=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=]";
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密文
P4mtWDzIIc2x/Taqc9T46A3T0aTCelmANBRf6RgEzSF29DLdMRiEhck98jac04+Tg0q7HpLalow0J6nZNUW+HWtRvYmLnt92UuIZ1ckaBEaLkpDfHZfp8g==
如您所见,两个输出 "almost" 相同(可能是由于填充,但目前这无关紧要。然而,这很奇怪,因为明文故意设置为 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[=12=][=12=][=12=][=12=][=12=][=12=]", -cipher => "Blowfish", -iv => "[=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=]", -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==
描述:你好你好你好你好你好你好你好你好你好你好你好你好你好
与Java程序不一样(与在线工具一致)虽然可以正确获取明文
所以也许我们在创建对象时没有提示相同的参数。特别是:
my $cipher = Crypt::CBC->new(-key => "1234567890[=13=][=13=][=13=][=13=][=13=][=13=]", -cipher => "Blowfish", -iv => "[=13=][=13=][=13=][=13=][=13=][=13=][=13=][=13=]", -literal_key => 1, -header => "none", -keysize => 16);
检查代码后,我唯一的猜测是 Java 和 Perl 使用不同的密钥大小,所以我的问题是
¿Java 使用的密钥大小是多少?在浏览了 SecretKeySpec here 的源代码后,我们无法确定这样的大小,因此假定为 128 位,因此大小为 16 (16 x 8 = 128) 和 \0 填充Perl 代码中的键。
当然,如果您能指出其他错误,将不胜感激。
在Java中,您使用
String Key = "1234567890";
在 Perl 中,您使用
my $key = "1234567890[=11=][=11=][=11=][=11=][=11=][=11=]";
如果您实际上使用了相同的密钥,您会得到相同的结果。
my $key = "1234567890";
-literal_key => 1, -key => $key, -keysize => length($key)
我们在 Java 和 Perl 中编写和应用程序,将加密的 CBC Blowfish 存储在同一个数据库中。双方都将加密和解密,因此他们需要能够获得对方加密的纯文本。
a) 我使用一些在线工具用 CBC 和 IV 向量加密了一些文本。一个这样的网站 is this
明文你好你好你好你好你好你好你好你好你好你好你好你好你好
钥匙 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 = "[=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=]";
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密文
P4mtWDzIIc2x/Taqc9T46A3T0aTCelmANBRf6RgEzSF29DLdMRiEhck98jac04+Tg0q7HpLalow0J6nZNUW+HWtRvYmLnt92UuIZ1ckaBEaLkpDfHZfp8g==
如您所见,两个输出 "almost" 相同(可能是由于填充,但目前这无关紧要。然而,这很奇怪,因为明文故意设置为 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[=12=][=12=][=12=][=12=][=12=][=12=]", -cipher => "Blowfish", -iv => "[=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=]", -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==
描述:你好你好你好你好你好你好你好你好你好你好你好你好你好
与Java程序不一样(与在线工具一致)虽然可以正确获取明文
所以也许我们在创建对象时没有提示相同的参数。特别是:
my $cipher = Crypt::CBC->new(-key => "1234567890[=13=][=13=][=13=][=13=][=13=][=13=]", -cipher => "Blowfish", -iv => "[=13=][=13=][=13=][=13=][=13=][=13=][=13=][=13=]", -literal_key => 1, -header => "none", -keysize => 16);
检查代码后,我唯一的猜测是 Java 和 Perl 使用不同的密钥大小,所以我的问题是
¿Java 使用的密钥大小是多少?在浏览了 SecretKeySpec here 的源代码后,我们无法确定这样的大小,因此假定为 128 位,因此大小为 16 (16 x 8 = 128) 和 \0 填充Perl 代码中的键。
当然,如果您能指出其他错误,将不胜感激。
在Java中,您使用
String Key = "1234567890";
在 Perl 中,您使用
my $key = "1234567890[=11=][=11=][=11=][=11=][=11=][=11=]";
如果您实际上使用了相同的密钥,您会得到相同的结果。
my $key = "1234567890";
-literal_key => 1, -key => $key, -keysize => length($key)