使用Ruby 1.8.6。
我正在编写一个基本服务器,它是一个加密版本,是客户端发送的消息,用于了解Ruby中对称加密的实现。该程序旨在接受套接字连接,共享它的密钥,然后加密它接收的数据,然后再将其发送回客户端程序。然后,客户端使用共享密钥解密消息,显示回声消息。
我遇到的问题是返回消息导致&#34;错误的最终块长度(OpenSSL :: CipherError)&#34;。进一步检查问题,删除decrypted << chiper.final
允许我的客户端程序解密消息,但最后添加其他字符或库空间。我知道这是因为final
关键字删除了额外的填充以允许16位块加密/解密CBC模式,但我无法弄清楚如何使工作正常。
这里有简化的服务器代码(我知道这不安全,不是重点,这只是一个学习应用程序)
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消息中删除额外的填充。
任何帮助将不胜感激。谢谢。
答案 0 :(得分:3)
studentFirst
和puts
处理字符串,而密文是二进制的。因此,如果您只是期望在gets
期间使用字符串然后换行,则会遇到问题(特别是如果您尝试解密最终换行符,这可能是导致错误的原因)。
相反,您可以先base 64 encode密文和 IV(单独)。然后gets
,解码并然后解密消息。
如果您只是gets.chomp
换行符,那么您的加密/解密可能也会起作用......直到您不小心在二进制密文的中间引入换行符。
所以永远不要忘记,尽管名称密文实际上不是文本(对于现代密码),但它是一个随机的二进制字节字符串。