Java 河豚示例,其中自动按大小填充和取消填充键
Blowfish具有强大的加密能力,可以使用多达56字节的密钥(448位密钥)。 密钥必须是8字节的倍数(最多56字节) 我想写的例子将自动填充和取消填充键的大小。因为Blowfish创建了8字节加密输出的块,所以输出也被填充并添加到8字节的倍数 实际上想编写java代码来模拟- 我正在使用工具的信息-Java 河豚示例,其中自动按大小填充和取消填充键,java,encryption,cryptography,blowfish,Java,Encryption,Cryptography,Blowfish,Blowfish具有强大的加密能力,可以使用多达56字节的密钥(448位密钥)。 密钥必须是8字节的倍数(最多56字节) 我想写的例子将自动填充和取消填充键的大小。因为Blowfish创建了8字节加密输出的块,所以输出也被填充并添加到8字节的倍数 实际上想编写java代码来模拟- 我正在使用工具的信息- ALGORITM = "Blowfish"; HEX KEY = "92514c2df6e22f079acabedce08f8ac3"; PLAIN_TEXT = "sangasong@son
ALGORITM = "Blowfish";
HEX KEY = "92514c2df6e22f079acabedce08f8ac3";
PLAIN_TEXT = "sangasong@song.com"
工具返回-
CD3A08381467823D4013960E75E465F0B00C5E3BAEFBECBB
请建议
尝试了java代码:
public class TestBlowfish
{
final String KEY = "92514c2df6e22f079acabedce08f8ac3";
final String PLAIN_TEXT = "sangasong@song.com";
byte[] keyBytes = DatatypeConverter.parseHexBinary(KEY);
}
public static void main(String[] args) throws Exception
{
try
{
byte[] encrypted = encrypt(keyBytes, PLAIN_TEXT);
System.out.println( "Encrypted hex: " + Hex.encodeHexString(encrypted));
}catch (GeneralSecurityException e)
{
e.printStackTrace();
}
}
private static byte[] encrypt(byte[] key, String plainText) throws GeneralSecurityException
{
SecretKey secret_key = new SecretKeySpec(key, "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, secret_key);
return cipher.doFinal(plainText.getBytes());
}
结果-
Encrypted hex: 525bd4bd786a545fe7786b0076b3bbc2127425f0ea58c29d
我不确定这个问题的相关性:我认为没有必要获得与此脚本相同的输出:您无法保证它的安全性/效率。。。 引起我注意的是填充部分:有几种填充块的解决方案,其中一些很简单,但非常不安全,可能这个脚本使用了其中一种“糟糕”的解决方案 您是否检查了您的程序是否能够检索到正确的纯文本?(您需要对匹配的
解密
函数进行编码)。
如果是这样的话,这意味着它工作正常,可以用于任何您最初的目的,无论此脚本的输出是什么…因此,脚本使用了错误版本的PKCS#7填充,当输入大小已经可以除以块大小时,它不会填充-键和明文都是如此。此外,它使用ECB模式加密。这两种方法都不应该在现实生活中使用 以下代码要求将Bouncy Castle提供程序添加到JCE(
Service.addProvider(new BouncyCastleProvider())
),并且Bouncy Castle库的十六进制类位于类路径中
警告:仅在有限输入下测试,如果钥匙尺寸大于最大值,则不会切割钥匙尺寸
警告:以下代码在加密方面不可靠
import org.bouncycastle.util.encoders.Hex;
public class BadBlowfish {
private static SecretKey createKey(String theKey) {
final byte[] keyData = theKey.getBytes(StandardCharsets.US_ASCII);
final byte[] paddedKeyData = halfPadPKCS7(keyData, 8);
SecretKey secret = new SecretKeySpec(paddedKeyData, "Blowfish");
return secret;
}
private static byte[] halfUnpadPKCS7(final byte[] paddedPlaintext, int blocksize) {
int b = paddedPlaintext[paddedPlaintext.length - 1] & 0xFF;
if (b > 0x07) {
return paddedPlaintext.clone();
}
return Arrays.copyOf(paddedPlaintext, paddedPlaintext.length - b);
}
private static byte[] halfPadPKCS7(final byte[] plaintext, int blocksize) {
if (plaintext.length % blocksize == 0) {
return plaintext.clone();
}
int newLength = (plaintext.length / blocksize + 1) * blocksize;
int paddingLength = newLength - plaintext.length;
final byte[] paddedPlaintext = Arrays.copyOf(plaintext, newLength);
for (int offset = plaintext.length; offset < newLength; offset++) {
paddedPlaintext[offset] = (byte) paddingLength;
}
return paddedPlaintext;
}
public static void main(String[] args) throws Exception {
Cipher cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");
SecretKey key = createKey("123456781234567");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plaintextData = cipher.doFinal(Hex.decode("085585C60B3D23257763E6D8BB0A0891"));
byte[] unpaddedPlaintextData = halfUnpadPKCS7(plaintextData, cipher.getBlockSize());
String plaintextHex = Hex.toHexString(unpaddedPlaintextData);
System.out.println(plaintextHex);
String plaintext = new String(unpaddedPlaintextData, StandardCharsets.UTF_8);
System.out.println(plaintext);
}
}
import org.bounchycastle.util.encoders.Hex;
公共级河豚{
私有静态SecretKey createKey(字符串theKey){
最终字节[]keyData=key.getBytes(标准字符集.US\u ASCII);
最后一个字节[]paddedKeyData=halfPadPKCS7(keyData,8);
SecretKey secret=新的SecretKeySpec(paddedKeyData,“河豚”);
归还秘密;
}
专用静态字节[]半UNPADPKCS7(最终字节[]填充明文,int blocksize){
int b=paddedPlaintext[paddedPlaintext.length-1]&0xFF;
如果(b>0x07){
返回paddedPlaintext.clone();
}
返回Arrays.copyOf(paddedPlaintext,paddedPlaintext.length-b);
}
专用静态字节[]halfPadPKCS7(最终字节[]明文,int blocksize){
if(明文.length%blocksize==0){
返回明文.clone();
}
int newLength=(plaintext.length/blocksize+1)*blocksize;
int paddingLength=newLength-plaintext.length;
最后一个字节[]paddedPlaintext=Arrays.copyOf(纯文本,newLength);
对于(int offset=plaintext.length;offset
建议。。。什么?到目前为止你试过什么吗?你为什么要按键?它应该以正确的大小生成。“那你为什么要解开它呢?”科科努普,我已经编辑了我的问题。请看看到目前为止我都试了些什么。很好!现在您是否运行它并遇到任何错误?没有错误。但输出和工具不同。我们的客户使用webnet77工具进行加密,并将加密代码发送给我们。在原始帖子中添加输出。@Coconop实际上尝试了各种方式和顺序进行加密,但从未得到与该工具相同的结果。非常感谢@owlstead。我对你的代码做了一些小的修改,得到了我想要的确切的解决方案。帮了大忙!!你认为当我从URL发送加密代码时,它不会工作吗??由于独立java程序工作得很好…但我遇到了一个异常-获取javax.crypto.IllegalBlockSizeException:使用填充密码解密时,输入长度必须是8的倍数?始终URL编码密文。确保发送和接收密文时密文是相同的。