4

Java の世界で明らかに人気のある暗号化ライブラリの Ruby 実装を取得しようとしています -- PBEWithMD5AndDES

openssl または別のオープン ソース gem を使用して、この形式と互換性のある暗号化/復号化を実行する方法を知っている人はいますか?

更新しました:

gem chilkatを使用 して実装しましたが、有料です。オープンソース ソリューションが必要です。

4

5 に答える 5

2

私はそれが非常に古いことを知っていますが、私は同じ問題を抱えていてそれを解決したので、ここで暗号化に行きます.saltはあなたのソルト文字列、passkeyはあなたのパスワードキー文字列、iterationsはあなたが使いたい繰り返しの数です.

def encrypt_account_number
cipher = OpenSSL::Cipher::Cipher.new("DES")
cipher.encrypt
cipher.pkcs5_keyivgen passkey, salt,iterations,digest
encrypted_account_number =  cipher.update(account_number)
encrypted_account_number << cipher.final
Base64.encode64(encrypted_account_number )
end

def decrypt_account_number
cipher = OpenSSL::Cipher::Cipher.new("DES")
base_64_code = Base64.decode64(account_number)
cipher.decrypt
cipher.pkcs5_keyivgen passkey, salt,iterations,digest

decrypted_account_number = cipher.update base_64_code
decrypted_account_number << cipher.final
decrypted_account_number
end
于 2013-08-16T06:26:49.600 に答える
1

ruby に DES 実装があるとすれば、実際に PBEWithMD5andDES を実装する必要はありません。実装する必要があるのは、キー派生関数 (パスワードからキーを取得する人) であり、その派生キーを適切なモードとパディングで DES にフィードします。

ありがたいことに、キー派生関数は実装においてセキュリティ上特に重要ではないため、十分に安全に自分で行うことができます。rfcによると、PBEwithMD5AndDES は、実際には CBC モードで DES とともに使用される PBKDF1 (カー派生関数) です。

PBKDF1 の実装はさほど難しくありません。forループとmd5呼び出しでできるようです。

Java と Ruby では異なるパディング スキームが使用されている可能性があるため、奇妙な結果が得られる可能性があることに注意してください。仕様はpkcs 1.5のパディングだと思いますが、パッと見では確認できません

5.1 PBKDF1

PBKDF1 は、キーを導出するために、MD2 [6]、MD5 [19]、または SHA-1 [18] であるハッシュ関数を適用します。派生キー
の長さは、ハッシュ関数出力の長さによって制限されます。これは、MD2 と MD5 では 16 オクテット、SHA-1 では 20 オクテットです。
PBKDF1 は、PKCS #5 v1.5の鍵派生プロセスと互換性があります。

PBKDF1 は、既存のアプリケーションとの互換性のためにのみ推奨されます。PBKDF1 が
生成するキーは、アプリケーションによっては十分に大きくない可能性があるため
です。

PBKDF1 (P、S、c、dkLen)

オプション: 基礎となるハッシュ関数のハッシュ

入力: P パスワード、オクテット文字列 S ソルト、8 オクテット文字列 c 反復カウント、正の整数 dkLen 派生キーのオクテット単位の長さ、正の整数、MD2 または MD5 の場合は最大 16、SHA-1 の場合は 20

出力: DK 派生キー、dkLen-octet 文字列

手順:

  1. If dkLen > 16 for MD2 and MD5, or dkLen > 20 for SHA-1, output
     "derived key too long" and stop.

  2. Apply the underlying hash function Hash for c iterations to the
     concatenation of the password P and the salt S, then extract
     the first dkLen octets to produce a derived key DK:

               T_1 = Hash (P || S) ,
               T_2 = Hash (T_1) ,
               ...
               T_c = Hash (T_{c-1}) ,
               DK = Tc<0..dkLen-1>

  3. Output the derived key DK.
于 2012-05-30T22:51:20.297 に答える
0

暗号化をサポートして、user3392439 の python スクリプトを更新しました。お役に立てば幸いです。

import base64
import hashlib
import re
import os
from Crypto.Cipher import DES

"""
Note about PBEWithMD5AndDES in java crypto library:

Encrypt:
  Generate a salt (random): 8 bytes
  <start derived key generation>
  Append salt to the password
  MD5 Hash it, and hash the result, hash the result ... 1000 times
  MD5 always gives us a 16 byte hash
  Final result: first 8 bytes is the "key" and the next is the "initialization vector"
  (there is something about the first 8 bytes needing to be of odd paraity, therefore
  the least significant bit needs to be changed to 1 if required. We don't do it,
  maybe the python crypto library does it for us)
  <end derived key generation>

  Pad the input string with 1-8 bytes (note: not 0-7, so we always have padding)
    so that the result is a multiple of 8 bytes. Padding byte value is same as number of
    bytes being padded, eg, \x07 if 7 bytes need to be padded.
  Use the key and iv to encrypt the input string, using DES with CBC mode.
  Prepend the encrypted value with the salt (needed for decrypting since it is random)
  Base64 encode it -> this is your result

Decrypt:
  Base64 decode the input message
  Extract the salt (first 8 bytes). The rest is the encoded text.
  Use derived key generation as in Encrypt above to get the key and iv
  Decrypt the encoded text using key and iv
  Remove padding -> this is your result

(I only have implemented decrypt here since that's all I needed,
but encrypt should be straighforward as well)

"""

def get_derived_key(password, salt, count):
    key = password + salt
    for i in range(count):
        m = hashlib.md5(key)
        key = m.digest()
    return (key[:8], key[8:])

def decrypt(msg, password):
    msg_bytes = base64.b64decode(msg)
    salt = msg_bytes[:8]
    enc_text = msg_bytes[8:]
    (dk, iv) = get_derived_key(password, salt, 1000)
    crypter = DES.new(dk, DES.MODE_CBC, iv)
    text = crypter.decrypt(enc_text)
    # remove the padding at the end, if any
    return re.sub(r'[\x01-\x08]','',text)

def encrypt(msg, password):
    salt = os.urandom(8)
    pad_num = 8 - (len(msg) % 8)
    for i in range(pad_num):
        msg += chr(pad_num)
    (dk, iv) = get_derived_key(password, salt, 1000)
    crypter = DES.new(dk, DES.MODE_CBC, iv)
    enc_text = crypter.encrypt(msg)
    return base64.b64encode(salt + enc_text)

def main():
    msg = "hello, world"
    passwd = "mypassword"
    s = encrypt(msg, passwd)
    print s
    print decrypt(s, passwd)

if __name__ == "__main__":
    main()
于 2014-07-30T09:58:59.157 に答える