質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

FuelPHP で 暗号化した文字列を Rubyで復号化

受付中

回答 1

投稿

  • 評価
  • クリップ 2
  • VIEW 2,483

JUNJUNJUN

score 25

 前提

FuelPHP 1.8
PHP 5.6.26
Amazon Linux
Ruby 2.1.5

 実行した内容

FuelPHPで顧客名を暗号化してDBに登録
暗号化は以下の方法で行いました。
http://fuelphp.jp/docs/1.8/classes/crypt/usage.html

 実現したいこと

RubyでDBに登録されている暗号化された顧客名(文字列)を使って復号化したい。
暗号のアルゴリズムがわかったら復号化できると思ったのですが、

 試したこと

def decrypt(pass, encrypted, iv)
  dec = OpenSSL::Cipher.new('aes-128-cbc')
  # 暗号化する際のキー文字列をセット
  dec.key = pass
  # Base64エンコードされたivをデコードしてセット
  dec.iv = Base64.decode64(iv) unless iv.nil?
  dec.decrypt
  plain_text = ""
  plain_text << dec.update(Base64.decode64(encrypted))
  plain_text << dec.final
  return plain_text
end


Rubyに登録されている全てのアルゴリズムを試しました。
※詳細は後述

 サーバー間で共有

crypto_key
crypto_iv
crypto_hmac    

 試したアルゴリズム

AES-128-CBC
AES-128-CFB
AES-128-CFB1
AES-128-CFB8
AES-128-CTR
AES-128-ECB
AES-128-OFB
AES-128-XTS
AES-192-CBC
AES-192-CFB
AES-192-CFB1
AES-192-CFB8
AES-192-CTR
AES-192-ECB
AES-192-OFB
AES-256-CBC
AES-256-CFB
AES-256-CFB1
AES-256-CFB8
AES-256-CTR
AES-256-ECB
AES-256-OFB
AES-256-XTS
AES128
AES192
AES256
BF
BF-CBC
BF-CFB
BF-ECB
BF-OFB
CAMELLIA-128-CBC
CAMELLIA-128-CFB
CAMELLIA-128-CFB1
CAMELLIA-128-CFB8
CAMELLIA-128-ECB
CAMELLIA-128-OFB
CAMELLIA-192-CBC
CAMELLIA-192-CFB
CAMELLIA-192-CFB1
CAMELLIA-192-CFB8
CAMELLIA-192-ECB
CAMELLIA-192-OFB
CAMELLIA-256-CBC
CAMELLIA-256-CFB
CAMELLIA-256-CFB1
CAMELLIA-256-CFB8
CAMELLIA-256-ECB
CAMELLIA-256-OFB
CAMELLIA128
CAMELLIA192
CAMELLIA256
CAST
CAST-cbc
CAST5-CBC
CAST5-CFB
CAST5-ECB
CAST5-OFB
DES
DES-CBC
DES-CFB
DES-CFB1
DES-CFB8
DES-ECB
DES-EDE
DES-EDE-CBC
DES-EDE-CFB
DES-EDE-OFB
DES-EDE3
DES-EDE3-CBC
DES-EDE3-CFB
DES-EDE3-CFB1
DES-EDE3-CFB8
DES-EDE3-OFB
DES-OFB
DES3
DESX
DESX-CBC
IDEA
IDEA-CBC
IDEA-CFB
IDEA-ECB
IDEA-OFB
RC2
RC2-40-CBC
RC2-64-CBC
RC2-CBC
RC2-CFB
RC2-ECB
RC2-OFB
RC4
RC4-40
RC4-HMAC-MD5
SEED
SEED-CBC
SEED-CFB
SEED-ECB
SEED-OFB
aes-128-cbc
aes-128-cfb
aes-128-cfb1
aes-128-cfb8
aes-128-ctr
aes-128-ecb
aes-128-gcm
aes-128-ofb
aes-128-xts
aes-192-cbc
aes-192-cfb
aes-192-cfb1
aes-192-cfb8
aes-192-ctr
aes-192-ecb
aes-192-gcm
aes-192-ofb
aes-256-cbc
aes-256-cfb
aes-256-cfb1
aes-256-cfb8
aes-256-ctr
aes-256-ecb
aes-256-gcm
aes-256-ofb
aes-256-xts
aes128
aes192
aes256
bf
bf-cbc
bf-cfb
bf-ecb
bf-ofb
blowfish
camellia-128-cbc
camellia-128-cfb
camellia-128-cfb1
camellia-128-cfb8
camellia-128-ecb
camellia-128-ofb
camellia-192-cbc
camellia-192-cfb
camellia-192-cfb1
camellia-192-cfb8
camellia-192-ecb
camellia-192-ofb
camellia-256-cbc
camellia-256-cfb
camellia-256-cfb1
camellia-256-cfb8
camellia-256-ecb
camellia-256-ofb
camellia128
camellia192
camellia256
cast
cast-cbc
cast5-cbc
cast5-cfb
cast5-ecb
cast5-ofb
des
des-cbc
des-cfb
des-cfb1
des-cfb8
des-ecb
des-ede
des-ede-cbc
des-ede-cfb
des-ede-ofb
des-ede3
des-ede3-cbc
des-ede3-cfb
des-ede3-cfb1
des-ede3-cfb8
des-ede3-ofb
des-ofb
des3
desx
desx-cbc
id-aes128-GCM
id-aes192-GCM
id-aes256-GCM
idea
idea-cbc
idea-cfb
idea-ecb
idea-ofb
rc2
rc2-40-cbc
rc2-64-cbc
rc2-cbc
rc2-cfb
rc2-ecb
rc2-ofb
rc4
rc4-40
rc4-hmac-md5
seed
seed-cbc
seed-cfb
seed-ecb
seed-ofb

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

+4

解決したので回答を更新します。これでFuel互換の暗号化と復号が行えます。

require 'openssl'
require 'base64'

class FuelCrypter

    def initialize(key, iv, hmac)
        @key = Base64.urlsafe_decode64(key)
        @iv = Base64.urlsafe_decode64(iv)
        @hmac = Base64.urlsafe_decode64(hmac)
    end

    def encode(value)
        cipher = OpenSSL::Cipher.new('aes-128-cbc')
        cipher.encrypt
        cipher.key = @key
        cipher.iv = @iv
        value = cipher.update(value) + cipher.final
        hmac = hmac_encode(value)
        Base64.urlsafe_encode64(value + hmac).gsub('=', '')
    end

    def decode(value)
        cipher = OpenSSL::Cipher.new('aes-128-cbc')
        cipher.decrypt
        cipher.key = @key
        cipher.iv = @iv
        value = Base64.urlsafe_decode64(value)
        hmac = value.slice!(-43, 43)
        if !secure_compare(hmac_encode(value), hmac)
            raise RuntimeError, 'invalid signature'
        end
        cipher.update(value) + cipher.final
    end

    private

    def secure_compare(a, b)
        a.bytesize == b.bytesize &&
        a.bytes.zip(b.bytes).map{|x,y| x^y}.reduce(&:|) == 0
    end

    def hmac_encode(value)
        Base64.urlsafe_encode64(OpenSSL::HMAC.digest('sha256', @hmac, value)).gsub('=', '')
    end

end

crypt = FuelCrypter.new(
    '9eEBP8okkcz4xAo9rU5h4f7Q',
    'HncqRUWjEl2Y53sqawnK4Y7Q',
    'ra4OxkVxYthofVMlAk0ncQrQ',
)

plain = 'テストテスト'
encoded = crypt.encode(plain)
p encoded # => "yIrEuHGvDsLoCsm0UMBw9r4BjpfikN1Ob4bPmA-qcfpWRkY0ZmtRZmM4OWdwanh6OG8xTzBLcF9abTlpMGRTWmF5WVI5THBZOFYw"

decoded = crypt.decode(encoded)
p decoded # => "\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88"
p decoded.force_encoding('utf-8') # => "テストテスト"

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/04 10:51

    もろもろ本当にありがとうございます。

    今回ご紹介いただいているRubyコードで暗号化すると、Fuel側のencrypted + "9" が 出力されます。
    また、長い文字列をRubyコードで暗号化すると、Fuel側のencrypted(255文字)+アルファが出力されました。
    ※Rubyコードの暗号化文字列の方が長くFuel側の方が255文字しかない。

    キャンセル

  • 2016/11/04 11:01

    現象が確認できる key, iv, hmac および暗号化対象文字列を出してもらえませんか?

    キャンセル

  • 2016/11/04 12:16

    ありがとうございます。
    Fuelチームに情報展開してご連絡いたします。
    懇切丁寧なご対応ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る