# How to sign messages with Ruby's OpenSSL RSA algorithm

In this post I’ll talk about signing and verifying messages. Imagine that I’m building a chat application. Messages will be sent via a pub/sub system like Pusher or Pubnub. Here is a simple JSON message object:

```
{
"user_id": "123",
"message": "Hello world!"
}
```

The problem with this implementation is that any user can be impersonated by changing the `user_id`

. To solve this problem, each user can sign their messages with a key that only they poses. One way to build this is to use RSA, an asymmetric cryptographic algorithm. Asymmetric algorithms generate two keys: one public and one private. The private key is used for signing messages and the public key is used for verifying messages. Here is how to write it in Ruby:

First, each user needs a public and private key:

```
rsa_key = OpenSSL::PKey::RSA.new(2048)
private_key_pem = rsa_key.to_pem #=> "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqd9paLELcSsdMA....\n-----END PUBLIC KEY-----\n,
public_key_pem = rsa_key.public_key.to_pem #=> "-----BEGIN RSA PRIVATE KEY-----\nMIIEogaY4wKPUV31NCZ\nYrJs+g47/zzHV5GYx5/Wv4zRhDyTi95....\n-----END RSA PRIVATE KEY-----\n,
```

Once keys have been generated, a message can be signed using the private key.

```
private_key = OpenSSL::PKey::RSA.new(private_key_pem)
signature = private_key.sign(OpenSSL::Digest::SHA256.new, 'Hello world!') #=> "\x04\xEC\xCC?\xDE\x8F\x91>G\..."
```

After the signature has been generated it can be sent along with the message.

```
{
"user_id": "123",
"message": "Hello world!",
"signature": "\x04\xEC\xCC?\xDE\x8F\x91>G\..."
}
```

A user can verify any message signature using the senders public key.

```
public_key = OpenSSL::PKey::RSA.new(public_key_pem)
public_key.verify(OpenSSL::Digest::SHA256.new, signature, message) #=> true/false
```

If the decoded signature matches the message then `#verify`

will return true. If not, the user’s public key does not match the one used to sign the message.

Of course, there must be a mechanism for distributing public keys to all users. In the case of a chat application, there could be an API that returns a list of participants with their public keys.