簡體   English   中英

Blowfish用Java / Scala加密並用bash解密

[英]Blowfish encrypt in Java/Scala and decrypt in bash

我正在嘗試構建一種工具來解密在Scala應用程序中加密的bash中的內容:

但是首先,我必須成功地用兩種語言編碼相同的消息並使它們相等:

給定密碼短語“ 0123456789abcdef”
(十六進制:“ 30313233343536373839616263646566”和byte []:[48、49、50、51、52、53、54、55、56、57、97、98、99、100、101、102])

scala> import javax.crypto.Cipher
scala> import javax.crypto.spec.SecretKeySpec
scala> val cipher = Cipher.getInstance("Blowfish")
scala> cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec("0123456789abcdef".getBytes("utf-8"), "Blowfish"))
scala> javax.xml.bind.DatatypeConverter.printBase64Binary(cipher.doFinal("message".getBytes("utf-8")))
res7: String = K679Jz06jmc=

但是我無法在bash中用openssl復制相同的內容。

$ echo "message" | openssl enc -a -e -blowfish -nosalt -nopad -k "0123456789abcdef"
LJ3iFJ2/mYk=
$ echo "message" | openssl enc -a -e -blowfish -nosalt -nopad -k "30313233343536373839616263646566"
JkkJgYv3fQg=

有什么提示嗎? 謝謝!

標記OpenSSL更准確,因為OpenSSL可以在任何shell或完全沒有shell上運行。

默認情況下,OpenSSL enc進行基於密碼的加密,其密鑰(加上IV)的派生類似於(但不完全是)PBKDF1。 要使用密鑰而不是密碼進行加密,您需要將UPPERCASE -K與十六進制一起使用,並且需要至少指定-iv一部分; 另一方面, -nosalt是沒有用的。

同樣, echo命令在其echo的數據上添加換行符 ,“ message NL”的加密與“ messag e”的加密完全不同。 某些操作系統和外殼程序(取決於所使用的echo是內置的還是外部的)可以省略換行符,但是它們並不完全相同。 OTOH所有POSIX系統都支持printf ,因此:

$ printf %s message | openssl enc -blowfish -K 30313233343536373839616263646566 -iv 00 -a
K679Jz06jmc=

編輯:Artjom是正確的; Java / Scala(可能)默認為ECB,這是一個壞主意; 您應該指定/CBC/CTR和填充。 與東陵/NoPadding不同,我認為您沒有理由強迫自己/NoPadding Java /PKCS5Padding與OpenSSL的默認兼容。 對於CBC或CTR,您需要顯式設置IV(使用Cipher.init的第三個參數)以獲得確定性的結果-您必須設置IV 或檢索默認的隨機IV來生成可解密的結果,人們通常想要的。 OpenSSL enc -blowfish默認為CBC,但更明確地聲明-bf-cbc-bf-ctr更為清晰。 -bf-ecb如果您確實想要ECB,則不建議使用上述建議)。

首先,如果要具有相同的密文,則必須確保Scala和OpenSSL加密使用具有相同輸入參數的相同確定性加密算法。

由於OpenSSL使用CBC作為默認模式,因此我們在Scala中執行相同的操作。

import javax.crypto.Cipher
import javax.crypto.spec._
import javax.xml.bind.DatatypeConverter

val cipher = Cipher.getInstance("Blowfish/CBC/NoPadding")

val key = new SecretKeySpec(DatatypeConverter.parseHexBinary("0123456789ABCDEF0123456789ABCDEF"), "Blowfish")

val specIv = new IvParameterSpec(DatatypeConverter.parseHexBinary("0000000000000000"))

cipher.init(Cipher.ENCRYPT_MODE, key, specIv)

val enc = cipher.doFinal("messages".getBytes("UTF-8"))

println(DatatypeConverter.printBase64Binary(enc))

請注意,沒有填充的輸入長度必須是Blowfish塊長度(64位)的倍數。

使用OpenSSL,您必須明確指定相同的密鑰和初始化向量(IV)

printf %s "messages" | openssl enc -e -blowfish -nopad -K "0123456789ABCDEF0123456789ABCDEF" -iv "0000000000000000" -base64

在上述示例中,在兩種情況下,您都將獲得JSj0k4FwtG8=作為密文。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM