[解決済み] OpenSSL AES-256-CBC 暗号化エラー、"間違った最終ブロック長" Ruby
質問
Ruby 1.8.6を使用しています。
私は、Ruby における対称型暗号の実装について学ぶために、クライアントから送信されたメッセージを暗号化して返す、基本的なサーバを書いています。このプログラムは、ソケット接続を受け入れ、秘密鍵を共有し、受信したデータを暗号化して、クライアントプログラムに送り返すように設計されています。クライアントは、共有された秘密鍵を使ってメッセージを復号化し、エコーされたメッセージを明らかにします。
私が遭遇している問題は、リターンメッセージが "間違った最終ブロック長 (OpenSSL::CipherError)" を引き起こすということです。この問題をさらに調査し
decrypted << chiper.final
私のクライアントプログラムはメッセージを復号化することができますが、最後に追加の文字またはバンクスペースが追加されます。私は、これは
final
キーワードは、CBCモードの16ビットブロック暗号化/復号化を可能にするために追加のパディングを削除しますが、どうすれば正しく動作するのかが分かりません。
以下は簡略化したサーバーコードです(これが安全でないことは分かっていますが、それは重要ではなく、これは単なる学習用アプリケーションです)。
require 'socket'
require 'thread'
require 'openssl'
require 'digest/sha1'
class Server
@@static_id = 1
@connection_no
@port
@server
@aes_cipher
@key
def initialize(p)
#setting up server connections
puts "Starting server"
@port = p
puts "connections on port #{@port} will be accepted"
@server = TCPServer.open(@port)
#generate a secret key
puts "creating secret key..."
@aes_cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
@aes_cipher.encrypt
@key = @aes_cipher.random_key
@aes_cipher.key = @key
puts "key: #{@key}"
#start server
start_server
end
def start_server
loop{
Thread.new(@server.accept) do |client|
#connection and request
sock_domain, remote_port, remote_hostname, remote_ip = client.peeraddr
client_ip = remote_ip.to_s
@@static_id += 1
@connection_no = @@static_id
puts "\nConnection ##{@connection_no} client #{client_ip} accepted"
#send client secret key
client.puts @key
#receive data from client
data = client.gets
puts "received: #{data}"
# you will need to store these for later, in order to decrypt your data
iv = @aes_cipher.random_iv
@aes_cipher.iv = iv
puts "generated IV: #{iv}"
encrypted = @aes_cipher.update(data)
encrypted << @aes_cipher.final
puts "Encrypted Msg: #{encrypted}"
#send back IV and data
client.puts encrypted
client.puts iv
#close connections
client.close
end
}
end
end
そして、私のクライアントは...
require 'socket'
require 'thread'
require 'openssl'
require 'digest/sha1'
class aes_client
@port
@hostname
def initialize(p)
@hostname = 'localhost'
@port = p
connect
end
def connect
#establis connections
s = TCPSocket.new(@hostname, @port)
#get key on connection
key = s.gets
puts "Key to decrypt: #{key}"
#send data
data = $stdin.gets.chomp
s.puts data
#receive message and IV
message = s.gets
puts "Encrypted Message: #{message}"
iv = s.gets
puts "IV to decypt: #{iv}"
# now we create a sipher for decrypting
cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
cipher.decrypt
cipher.key = key
cipher.iv = iv
# and decrypt it
decrypted = cipher.update(message)
#decrypted << cipher.final
puts "decrypted: #{decrypted}\n"
s.close
end
end
クライアントはキーボードから情報を取得し、これをサーバーに送信した後、暗号化されたメッセージの返信を待ちます。前にも言ったように、私は
decrypted << cipher.final
を正しく動作させたり、echoされたメッセージから追加のパディングをうまく削除することができます。
何かお手伝いいただけると幸いです。ありがとうございます。
解決方法は?
puts
と
gets
は文字列に対して動作しますが、暗号文はバイナリです。ですから、文字列を期待して
gets
(特に最後の改行も復号化しようとすると、おそらくこれがエラーの原因になります)。
その代わりに、まず
ベース64エンコード
暗号文の
と
IV(別々に)。次に
gets.chomp
は、デコードし
では
を復号化する。
もし、あなたがただ
chomp
バイナリ暗号文の途中に誤って改行を入れてしまうまでは、暗号化も復号もうまくいくでしょう。
つまり、暗号文は名前に反して実際にはテキストではなく(最近の暗号では)、ランダムなバイナリバイト列であることを決して忘れないでください。
関連
-
[解決済み] Rubyで新しい文字列を作成せずに文字列をトリミングする標準的な方法は何ですか?
-
[解決済み] Rubyでファイル名を変更するには?
-
[解決済み] nil:NilClass のための未定義のメソッド `+' (NoMethodError)
-
[解決済み] Rubyで日付文字列をパースする
-
[解決済み] レイルズ・ジェネレート」を逆手に取る方法
-
[解決済み] rubyでto_yamlに書式オプションを指定することはできますか?
-
[解決済み] Rubyの予期しないキーワードの終了、および予期しない入力の終了
-
[解決済み] Rubyにバイナリ検索は組み込まれていますか?
-
[解決済み] AES暗号化モード(CBC ECB CTR OCB CFB)の選択方法は?
-
[解決済み] Java 256ビットAESパスワードベース暗号化機能
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Ruby:kind_of? vs. instance_of? vs. is_a?
-
[解決済み] -bashです。/Users/myname/.bash_profile: パーミッションが拒否されました
-
[解決済み] ルビー階乗関数
-
[解決済み] Ruby、スタックレベルが深すぎる (SystemStackError)
-
[解決済み] 配列をアルファベット順に並べるには?
-
[解決済み] Capybaraを使ったドロップダウンでのオプションの選択方法
-
[解決済み] Rubyでリフレクション?
-
[解決済み] Ruby で PDF 文書を解析する
-
[解決済み] ネストされたクラスとモジュールにネストされたクラスはいつ使用するのですか?
-
[解決済み] Rubyの予期しないキーワードの終了、および予期しない入力の終了