在Java中加密和解密 - 为什么不起作用? [英] Encrypt in Ruby and Decrypt in Java - Why is it not working?

查看:139
本文介绍了在Java中加密和解密 - 为什么不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做错了什么?我希望Java程序打印私人。我的目标是尝试在Java中编写MessageEncryptor.decrypt ruby​​方法。



Ruby加密(大多数代码来自MessageEncryptor,但不修改为Marshal),但是提取出来,这样可以更容易地看到发生了什么:

  require'openssl'
require'active_support / base64'

@cipher ='aes-256-cbc'
d = OpenSSL :: Cipher.new(@cipher)
@secret = OpenSSL :: PKCS5.pbkdf2_hmac_sha1(密码,一些盐,1024,d.key_len)
cipher = OpenSSL :: Cipher :: Cipher.new(@cipher)

iv = cipher.random_iv

cipher.encrypt
cipher.key = @secret
cipher.iv = iv

encrypted_data = cipher.update(private)
encrypted_data< ;< cipher.final

puts [encrypted_data,iv] .map {| v | :: Base64.strict_encode64(v)}。join( - )

哪个打印: / p>

tzFUIVllG2FcYD7xqGPmHQ == - UAPvdm3oN3Hog9ND9HrhEA ==



Java代码:

  package decryptruby; 

import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

public class DecryptRuby {
public static String decrypt(String encrypted,String pwd,byte [] salt)
throws异常{

String [] parts = encrypted.split( - );
if(parts.length!= 2)return null;

byte [] encryptedData = Base64.decodeBase64(parts [0]);
byte [] iv = Base64.decodeBase64(parts [1]);

SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF2WithHmacSHA1);
KeySpec spec = new PBEKeySpec(pwd.toCharArray(),salt,1024,256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey aesKey = new SecretKeySpec(tmp.getEncoded(),AES);


密码密码= Cipher.getInstance(AES / CBC / PKCS5Padding);
cipher.init(Cipher.DECRYPT_MODE,aesKey,new IvParameterSpec(iv));

byte [] result = cipher.doFinal(encryptedData);
return result.toString();
}


public static void main(String [] args)throws异常{
String encrypted =tzFUIVllG2FcYD7xqGPmHQ == - UAPvdm3oN3Hog9ND9HrhEA ==;

System.out.println(Decrypted:+ decrypt(encrypted,password,some salt.getBytes()));
}
}

哪些打印



解密:[B @ 432a0f6c

解决方案

这是问题 - 或至少 / em>问题:

  byte [] result = cipher.doFinal(encryptedData); 
return result.toString();

您正在调用 toString()一个字节数组。数组不覆盖 toString()。这不会给你你想要的 - 你可以看到。相反,你需要写一些,例如:

  return new String(result,UTF-8 ); 

...但您需要知道使用哪种编码加密前的原始字符串为字节。我从Ruby代码中不清楚使用什么编码,但如果你可以明确地说明(理想情况下是使用UTF-8),这将使你的生活更容易。


$ b $简而言之,我怀疑这个问题与加密无关,它与Ruby中的文本转换为字节有关,然后将相同的字节序列转换为字符串在Java。



当然,加密可能会失败,但这是一个不同的事情。


What am I doing wrong? I expected the Java program to print "private". My goal is to try to write the MessageEncryptor.decrypt ruby method in Java.

Ruby encryption (most code was taken from MessageEncryptor, but modified not to Marshal), but I've extracted it so that it's easier to see what's going on:

require 'openssl'
require 'active_support/base64'

@cipher = 'aes-256-cbc'
d = OpenSSL::Cipher.new(@cipher)
@secret = OpenSSL::PKCS5.pbkdf2_hmac_sha1("password", "some salt", 1024, d.key_len)
cipher = OpenSSL::Cipher::Cipher.new(@cipher)

iv = cipher.random_iv

cipher.encrypt
cipher.key = @secret
cipher.iv = iv

encrypted_data = cipher.update("private")
encrypted_data << cipher.final

puts [encrypted_data, iv].map {|v| ::Base64.strict_encode64(v)}.join("--")

Which printed:

tzFUIVllG2FcYD7xqGPmHQ==--UAPvdm3oN3Hog9ND9HrhEA==

Java code:

package decryptruby;

import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

public class DecryptRuby {    
    public static String decrypt(String encrypted, String pwd, byte[] salt)
            throws Exception {

        String[] parts = encrypted.split("--");
        if (parts.length != 2) return null;

        byte[] encryptedData = Base64.decodeBase64(parts[0]);
        byte[] iv = Base64.decodeBase64(parts[1]);

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(pwd.toCharArray(), salt, 1024, 256);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKey aesKey = new SecretKeySpec(tmp.getEncoded(), "AES");


        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(iv));

        byte[] result = cipher.doFinal(encryptedData);
        return result.toString();
    }


    public static void main(String[] args) throws Exception {
        String encrypted = "tzFUIVllG2FcYD7xqGPmHQ==--UAPvdm3oN3Hog9ND9HrhEA==";

        System.out.println("Decrypted: " + decrypt(encrypted, "password", "some salt".getBytes()));
    }
}

Which printed

Decrypted: [B@432a0f6c

解决方案

This is the problem - or at least a problem:

byte[] result = cipher.doFinal(encryptedData);
return result.toString();

You're calling toString() on a byte array. Arrays don't override toString(). That won't give you what you want at all - as you can see. Instead, you need to write something like:

return new String(result, "UTF-8");

... but you need to know what encoding was used to turn the original string into bytes before encryption. It's not clear to me from the Ruby code what encoding is used, but if you can be explicit about it (ideally using UTF-8) it'll make your life a lot easier.

In short, I suspect this problem has nothing to do with encryption at all - it has everything to do with converting text to bytes in Ruby and then converting the same sequence of bytes back into a string in Java.

Of course the encryption may be failing as well but that's a different matter.

这篇关于在Java中加密和解密 - 为什么不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆