2016-05-29 140 views
1

我需要加密使用OpenSSL::Cipher::AES一些固定大小號,但是我難以理解什麼包裝的組合,我需要使用獲得的已知結果。如何加密使用OpenSSL ::密碼

我有Java的參考代碼如下:

import java.io.UnsupportedEncodingException; 
import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.NoSuchAlgorithmException; 
import javax.crypto.Cipher; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 
import org.apache.commons.codec.DecoderException; 
import org.apache.commons.codec.binary.Base64; 
import org.apache.commons.codec.binary.Hex; 
import com.google.common.primitives.Longs; 

class Encryptor { 
    private String initialVector; 
    private static final String TRANFORMATION = "AES/CBC/PKCS5Padding"; 
    private static final String ALGORITHM = "AES"; 

    String encrypt(SecretKeySpec key, long timestamp) throws Exception { 
    byte[] encryptedBytes = getEncryptingCipher(key).doFinal(Longs.toByteArray(timestamp)); 
    return Base64.encodeBase64String(encryptedBytes); 
    } 

    private Cipher getEncryptingCipher(SecretKeySpec key) throws 
    NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, 
    InvalidKeyException, 
    InvalidAlgorithmParameterException { 
     Cipher encryptingCipher = Cipher.getInstance(TRANFORMATION); 
     encryptingCipher.init(Cipher.ENCRYPT_MODE, key, new 
      IvParameterSpec(initialVector.getBytes())); 
     return encryptingCipher; 
    } 

    private SecretKeySpec getSecretKeySpec(String key) throws DecoderException { 
    byte[] keyBytes = Hex.decodeHex(key.toCharArray()); 
    return new SecretKeySpec(keyBytes, ALGORITHM); 
    } 

    void setInitialVector(String initialVector) { 
    this.initialVector = initialVector; 
    } 

    public static void main(String[] args) throws Exception { 
    Encryptor encryptor = new Encryptor(); 
    encryptor.setInitialVector("0000000000000000"); 
    //Expensive operation so only performed once, re-use the key spec instance 
    SecretKeySpec keySpec = 
    encryptor.getSecretKeySpec("b35901b480ca658c8be4341eefe21a80"); 
    long timestamp = 1464284796L; //System.currentTimeMillis()/1000; 
    String authToken = encryptor.encrypt(keySpec, timestamp); 
    System.out.println(authToken); 
    } 
} 

導致以下base64編碼字符串被打印在控制檯上:6BH3hg1cqQJOK6sG8gw7Xw==

我試圖複製這種使用OpenSSL::Cipher,但我沒有運氣。 Ruby OpenSSL文檔缺乏細節。我懷疑我的包裝使用不正確。

require "openssl" 

key = ['b35901b480ca658c8be4341eefe21a80'].pack('H*') 
iv = '0000000000000000' 
message = [1464284796].pack "N*" 

cipher = OpenSSL::Cipher::AES.new(128, :CBC) 
cipher.encrypt 

cipher.iv = iv 
cipher.key = key 

encrypted = cipher.update(message) 
encrypted << cipher.final 

cipher64 = [encrypted].pack('m') 

puts "Generated: " + cipher64 
puts "Expected : " + '6BH3hg1cqQJOK6sG8gw7Xw==' 

回答

2

番石榴文檔說爲Longs#toByteArray(long)

toByteArray(long value)
返回value在一個8字節元件陣列的大端表示;相當於ByteBuffer.allocate(8).putLong(value).array()

但Ruby的Array#pack "N*"編碼一個32位無符號整數,結果爲4個字節。

message = [0, 1464284796].pack "N*" 

或在評論matt筆記使用大端64位整數:

message = [1464284796].pack "Q>" 
+1

你也可以使用'Q>'所以,你可以簡單地用4個零填充它,它會直接給你一個64位無符號值,而不需要添加額外的零。 – matt