Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/52.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使java密码算法和ruby密码算法同步?_Java_Ruby On Rails_Encryption_Aes - Fatal编程技术网

如何使java密码算法和ruby密码算法同步?

如何使java密码算法和ruby密码算法同步?,java,ruby-on-rails,encryption,aes,Java,Ruby On Rails,Encryption,Aes,我的rails应用程序中有以下代码: require 'openssl' require 'digest/sha1' require 'base64' KEY="secret_key" data = "secret message" def encrypt_value(data) cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc") cipher.encrypt cipher.key = Digest::SHA25

我的rails应用程序中有以下代码:

require 'openssl'
require 'digest/sha1'
require 'base64'

KEY="secret_key"
data  = "secret message"

 def encrypt_value(data)
    cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
    cipher.encrypt
    cipher.key = Digest::SHA256.digest(KEY)
    encrypted = cipher.update(data)+cipher.final
    return encrypted
 end

def decrypt_value1(data)
    cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
    cipher.decrypt
    cipher.key = Digest::SHA256.digest(KEY)
    decrypted = cipher.update(data)+cipher.final
    data = Base64.decode64(decrypted)
    return data
end
和java代码:

import java.security.AlgorithmParameters; 
import java.security.NoSuchAlgorithmException; 
import java.security.SecureRandom; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.PBEKeySpec; 
import javax.crypto.spec.SecretKeySpec; 
import javax.xml.bind.DatatypeConverter; 

public class EncryptionDecryption { 

    private static String salt; 
    private static int iterations = 65536  ; 
    private static int keySize = 256; 
    private static byte[] ivBytes; 

   // private static SecretKey secretKey; 
    private static final byte[] secretKey = "secret_key".getBytes(); 

    public static void main(String []args) throws Exception { 

        salt = getSalt(); 

        char[] message = "secret message".toCharArray(); 
        System.out.println("Message: " + String.valueOf(message)); 
        System.out.println("Encrypted: " + encrypt(message)); 
        System.out.println("Decrypted: " + decrypt(encrypt(message).toCharArray())); 
    } 

    public static String encrypt(char[] plaintext) throws Exception { 
        byte[] saltBytes = salt.getBytes(); 

        SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
        PBEKeySpec spec = new PBEKeySpec(plaintext, saltBytes, iterations, keySize); 
        //secretKey = skf.generateSecret(spec); 
        SecretKeySpec secretSpec = new SecretKeySpec(secretKey, "AES"); 

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
        cipher.init(Cipher.ENCRYPT_MODE, secretSpec); 
        AlgorithmParameters params = cipher.getParameters(); 
        ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV(); 
        byte[] encryptedTextBytes = cipher.doFinal(String.valueOf(plaintext).getBytes("UTF-8")); 

        return DatatypeConverter.printBase64Binary(encryptedTextBytes); 
    } 

    public static String decrypt(char[] encryptedText) throws Exception { 

        System.out.println(encryptedText); 

        byte[] encryptedTextBytes = DatatypeConverter.parseBase64Binary(new String(encryptedText)); 
        SecretKeySpec secretSpec = new SecretKeySpec(secretKey, "AES"); 

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

        byte[] decryptedTextBytes = null; 

        try { 
            decryptedTextBytes = cipher.doFinal(encryptedTextBytes); 
        }   catch (IllegalBlockSizeException e) { 
            e.printStackTrace(); 
        }   catch (BadPaddingException e) { 
            e.printStackTrace(); 
        } 

        return new String(decryptedTextBytes); 

    } 

    public static String getSalt() throws Exception { 

        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); 
        byte[] salt = new byte[20]; 
        sr.nextBytes(salt); 
        return new String(salt); 
    } 
}

如何让这两个应用程序相互配合,例如,如果我从rails应用程序向java应用程序发送加密数据,它应该能够解码,反之亦然。

只要您使用相同的密码算法和消息填充字符,它们就可以正常工作

此外,最好使用一些密钥交换协议,如Diffie-Hellman。Ruby的OpenSSL包装器和Java的加密库都支持它。这是生成每个会话密钥的更安全的方法


另外,您的代码似乎是为独立执行而编写的。例如,用于解码的Java代码假设字符串是使用同一实例的
encode
方法编码的。因为,您的
decode
方法使用的是在
encode
方法(
ivBytes
)中初始化的IV。

这两个版本中应该保留哪一个?您在ruby中使用了简单的加密,而在java中使用了带salt的PBKDF。你可以在任何一种语言中使用任何一种版本,但你必须指定你想要的版本。salt和IV都不是秘密,需要被加密和解密双方都知道。它们可以在不影响安全性的情况下以纯文本形式发送。如果您选择其中一个或两个,则必须传输它们(或选择固定的,但这使它们基本上不必要)。您需要知道secretkey/加密密码。使用salt/iv会使计算更加困难,因为生成的加密数据会进一步随机化。例如,您可以不使用(每次不同)iv,仅通过比较加密数据来识别相同的消息
InvalidKeyException:当您没有无限强度加密时,会发生非法密钥大小
,因为默认java安装只允许aes-128及以下的密钥大小。无论是独立应用程序还是服务器应用程序,当您使用java安装运行程序时,始终会加载您安装的文件。当它只在一个环境中工作时,您可能正在使用不同的java版本并排安装。什么是计数:0,…的东西,我不知道你一定把它放进了加密的blob,如果它从那里出来的话。加密不会改变数据,也不依赖于操作系统。感谢@Uzbekjon,我必须尝试密钥交换协议,从现在起,如果我尝试解码从Java应用程序接收到的加密消息,我会收到一个错误消息,说错误的最终块。我无法找出它们是如何给出相同的编码信息的。将尝试您的方法并在此处更新。如果问题出现在最后一个块中,则可能是由于ruby和java中使用的不同填充字符造成的。你应该研究一下。还有一件事我不确定,在java中它使用iv键,所以我尝试获取iv值,并在ruby中使用它,cipher.iv=相同的_键,再加上ruby中使用的键,它说它太短,所以我使用SHA256将其转换为256位,我不确定这是不是用Java实现的。只需调试你的应用程序并检查它就可以了。或者只是查看文档。Java文档非常详细。我想说的太详细了)有没有一种方法,我可以用ruby编写一个与上面用Java编写的程序类似的程序?从昨天开始我一直在尝试同步它。因为java代码中发生了很多事情,比如,iv、salt、迭代和密钥,这些在我当前的代码中是不存在的。