OpenSSL encryption error AES-256-CBC, Ruby "wrong end block length"

Using Ruby 1.8.6.

I am writing a basic server that echo the encrypted version sends a message from the client to inquire about the symmetric encryption implementation in Ruby. The program is designed to accept a socket connection, exchange a secret key, then encrypt the data it receives before sending it back to the client program. The client then decrypts the message using the shared secret, showing the echo'd message.

The problem I am facing is a return message that throws "wrong final block length (OpenSSL :: CipherError)". After looking at the issue, deleting decrypted <<

allows my client program to decrypt the message, but adds extra characters or bank spaces at the end. I know this is because the keyword final

removes the extra padding to allow 16-bit encryption / decryption of the CBC mode block, but I can't figure out how to get the job done correctly.

Here's a simplified server code (I know it's not secure, it isn't, this is just a tutorial application)

require 'socket'
require 'thread'
require 'openssl'
require 'digest/sha1'

class Server 
@@static_id = 1



def initialize(p)
    #setting up server connections
    puts "Starting server"      
    @port = p
    puts "connections on port #{@port} will be accepted"
    @server =

    #generate a secret key
    puts "creating secret key..."
    @aes_cipher ="aes-256-cbc")
    @key = @aes_cipher.random_key
    @aes_cipher.key = @key
    puts "key: #{@key}"

    #start server       

def start_server    
    loop{ 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 <<  
            puts "Encrypted Msg: #{encrypted}"              

            #send back IV and data
            client.puts encrypted
            client.puts iv              

            #close connections



And my client ...

require 'socket'
require 'thread'
require 'openssl'
require 'digest/sha1'

class aes_client

def initialize(p)
    @hostname = 'localhost'
    @port = p

def connect
    #establis connections
    s =, @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 ="aes-256-cbc")
    cipher.key = key
    cipher.iv = iv

    # and decrypt it
    decrypted = cipher.update(message) 
    #decrypted <<

    puts "decrypted: #{decrypted}\n"



The client takes the information from the keyboard and sends it to the server before waiting for an encrypted message in response. As said, I can't think of waiting for it to decrypted <<

work correctly or successfully removing the extra addition from the echo'd message.

Any help would be greatly appreciated. Thank you.


source to share

1 answer


and gets

work with strings, and the ciphertext is binary. So you're in trouble if you're just expecting a string and then a newline in time gets

(especially if you try to decode the final newline as well, this is probably causing the error).

Instead, you could base 64 encode the ciphertext and IV (separately) first. Then gets.chomp

, decode and then decode the message.

If you're just a chomp

newline, then your encryption / decryption will probably work too ... as long as you don't accidentally enter a newline in the middle of the binary ciphertext.

So never forget that despite the name, the ciphertext is not actually text (for modern ciphers), it is a random binary string of bytes.



All Articles