CategoriesSecurity

Crimediggers | Decrypting Base64 messages using RSA private keys – Encrypted Data: (chuckles) I’m in danger.

A friend of mine was doing an online interactive puzzle/game called Crimediggers developed by the Dutch law enforcement agency, and he asked if I could help him with decrypting some encoded messages.. Hmm, interesting!

He already collected the encoded messages and has obtained the private keys. We are not sure which private key belongs to which encoded message.

Encoded Messages

These are the encoded messages in question:

mLkcoaOGPIdIDUnoWdKd0rca66fMWE/bs0YUJWS9waiPrxJQr6KMbL2le/DYtDDKy+cl8EKj0Q1LL9duUpdhszFGYjC98j2tu38lnb3Im5aevhqqo7mds+ZuE2XNtzEJ2dXdSYzhZvzkT6bKKHfFnMr9+WQzUKG9IQiHxg0eBZRvQJFViTY/3aADE11GDs6S4dbvv4sT8MwQva1rGD/Q+d/kAU+av8pRaTlI1fRdESPtHHljkBev7s5fZRJGki1gtwNiInhmajA23x/oSPBTBPzMIR4K5/OIJ2tRCRDmAUvTETNloh6EpOz+vJR+RkbFv6rZIVaxV3yq1dIKYg54hQ==
W1hkk4XxKglKgRo96MQw0glw+O3WpH2OwSy2I+NbWdQ+dYtdJzR1shwCbacCdzF+DNPa07FWhHUE+An6CD8sRPLRyuXR/p8goehgLG3iPma1gyut0VjHyNDIJsJSu4gvnrEcfiWdEYGUKw+NFeYsvDniyOnH/d3BAli8lM8PDxgZjJ6lQ5EZnjQOGS4l2DZWU1lVXfMukK9/5nAO4h41pSCK8ultYFdEk8sdrf3Td2XVp/EIGI9XCwTAZ8H2+XP/eCO4ecgN3GRjttkdQYUhqvlnCaHpsQyNCGzJQpAOycAj/GDTtQ+EoSfVtEAnmOCZRFk12fy8PL+XnUEI/SwIQg==
UdMsi/STSeUBkVUucCBJWwbUzzF0v8bay0suQg9WvBglwZFoGgAVK48d8AWIhEa1euqkF8O2lv4Sprihlzt+HFNEcf1QADyOTZpK+O9PrtEie9o48TbEaFbxSUImepBzLF2/YxSbKhfGYUNb+4MfOn7r0mLmFeslCNQoH/ZfNW76QZ5/0z0HPZOWCCfAEM6n/L7ERh77h4pemGz8UYLTw12TsBNaNeA4vzqNVTtLnzUpcrFrwJrnBOPjw78Ce/jN/8BNhc+PKwvSQw2yqdAUly6+dUq2W/VEuCK3Q+/ilqtRgu5KZBDlarHgMVeS+Sn0dNleiqB0sPUV5O/PPjGE2A==
UxWL9nhlgZUxdbQDMYs6rDcoqHpSKOPN9c32I2+F4pv3FcxNtUh8TcoF0TBe2MoitglYRsRXIKdVl1MmVQUnb9L+QWSaNlgI/GkI9gXrtUIpS6ZluyJzTzKwwh47BKW7d/3YlrenbL0f8PYy7y2JcZK7gJLcp2AJVNkFAlgKZWdcjjvqdY2GoB7GDtztMSqjM27Zs0DgSv3p6QIqJuWMe3eCQhdMGASBcShItd+wQd1z/3nNvmY5Mk5xC7RahIMi4UZitSgLb6cLKfNmIrre9mDZwnHJxpCtLmgh54pW8ACEpo2qfW/dcAa4dtQebwo7HcpixMzcj7rGon0l+pg5HQ==

From these four messages we can establish a couple of things:

  1. Modern encryption algorithms usually outputs into random bytes and yet this message seems to be formatted in a plain text format. This suggests that some kind of binary-to-text encoding have been applied.
  2. The messages seems to be formatted in Base64 because the content resembles a ASCII string and ends with two == symbols.

Let’s check if the messages are indeed Base64. Using regular expression (RegEx) we can determine that the text could have been a Base64 value. However, even if the message passes the RegEx, this does not mean that the decoded content is valid encrypted content. That’s the beauty of encryption! If we assume that it’s encrypted using modern algorithms, we can’t really know for sure that the file is encrypted because it should look randomized.

^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$

We can confirm that each of the four messages are a full match with the RegEx above. Now we need to convert those Base64 encoded messages back to file.

Why? Because we need the original encrypted file to decrypt using the private keys. We can’t apply the private key directly to the Base64 encoded messages. You’ll get a error like:

RSA operation error
19200:error:0406506C:rsa routines:rsa_ossl_private_decrypt:data greater than mod len:crypto\rsa\rsa_ossl.c:401:

The private key should be applied to the output that was generated during the encryption process and not on the Base64 encoded version of it.

Just some additional information…

There’s a lot of ways to do this but since I’m primarily on Windows, I’ll do this with PowerShell. The following script need two variables: $path and $message. The $path variable is where the output of the file will be exported. The $message variable contains the Base64 encoded message. Both variables will be passed into a FromBase64String function.

The FromBase64String method is designed to process a single string that contains all the data to be decoded. Converts the specified string, which encodes binary data as base-64 digits, to an equivalent 8-bit unsigned integer array.

Just some additional information…
$path = 'C:\Temp\encrypted1.bin'
$message = 'mLkcoaOGPIdIDUnoWdKd0rca66fMWE/bs0YUJWS9waiPrxJQr6KMbL2le/DYtDDKy+cl8EKj0Q1LL9duUpdhszFGYjC98j2tu38lnb3Im5aevhqqo7mds+ZuE2XNtzEJ2dXdSYzhZvzkT6bKKHfFnMr9+WQzUKG9IQiHxg0eBZRvQJFViTY/3aADE11GDs6S4dbvv4sT8MwQva1rGD/Q+d/kAU+av8pRaTlI1fRdESPtHHljkBev7s5fZRJGki1gtwNiInhmajA23x/oSPBTBPzMIR4K5/OIJ2tRCRDmAUvTETNloh6EpOz+vJR+RkbFv6rZIVaxV3yq1dIKYg54hQ=='
$bytes = [Convert]::FromBase64String($message)
[IO.File]::WriteAllBytes($path, $bytes)

We will execute this script four times, each time with a different encoded message. In the end, we will have 4 encrypted files that needs to be decrypted.

Private Keys

Now that we have our encoded messages sorted out, let’s go and take a look at the private keys. The private keys are bundled up in a single file looking like this:

-----BEGIN RSA PRIVATE KEY-----
***
-----END RSA PRIVATE KEY-----
-----BEGIN RSA PRIVATE KEY-----
***
-----END RSA PRIVATE KEY-----
-----BEGIN RSA PRIVATE KEY-----
***
-----END RSA PRIVATE KEY-----

This tells us that we are dealing with an RSA private key. We can confirm this by performing the following command in OpenSSL.

openssl rsa –noout –check –in $privateKey | openssl md5

The $privateKey variable is used in the “-in” parameter for the input of the private key. It expects a path to the private key file.

If OpenSSL outputs anything else than “RSA key ok” then the key is invalid. In this specific scenario, the private keys are all valid RSA private keys. I will post the private keys in the second page of this post since there are 10 private keys in the bundle. Now I am going to split up each segment into separate files.

Be sure to include —-BEGIN RSA PRIVATE KEY—- and —–END RSA PRIVATE KEY—– in the text when separating the private keys from the bundle.

Important!

This means that I end up with 10 files looking like this:

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3qyBdDzhyyftmxd/FjRHbgtlRnMh8pcBHJVhUe9FNTRsftrF
+9sX2kSoGKSDpmbD0TMckwj8dpWRfVvA5f7xNcPzVlG7HX8FQeIcQjnTFhkWwuNa
LfGD4IXswc82vyYLdW6B5njEKi4I35CkGuOGRqohUuSeiXTlZ6ZaO5HYXZGJ7yCI
1/UGTl5IFuvdqpymqe55egSXN/XrH3Uym5p5Sqh/xtls51ZRl0hMIJZsMVQLb0nf
TrdXWCLfnlmElso5aA02+gi41Ax9c6AreRltXATDQGgFJR9qNs4SE4olJ95shJra
kBnQayNFGrNkDEX4uW48vJ4c2KzRQF1Ujr2irwIDAQABAoIBAGzPjT7Y1Vlp/IDy
HWcjSthqdyXS8v7RbXijQnhAXOhf4rimfWLSMDi3nhDUq4Rv6TZcLJVpKb1k30CL
yppZV1N3mnxO2gnS3SXRsQ9npE/DGM1JPfL/dvsLVqNqd402sRjEVHPkBa+66Rke
XCLLlf0H+9q+3v26grOApc1AOqOVppbYFez7m06RtFWJ2pz3jwk7t0gHYEaBf710
IVwWcLw9OnkX/xo/dwHoBOHfp+0UJ0W83F11Pp4GiE5DoFoS7FYIKa++RrRonJOB
UpgCzr+8yarlZaztCZk0cUS/ck1G9KkDQ4qE1ZG2Cnsd6TS2JlxEEGavQyjy4/Q1
U2IBk9ECgYEA85pb4NqiuCcM8E0ReRRX1yR9yoURJPsbFo2FTz4GNydefqzIovrN
uE5p47E44Y4dtiemcJ+sAntNiXDXriZkOE0QZe90ynHIdOcGpuvWK5A2LnMc82iS
sMv5vd8bzeWX0I/z9C3A/hzjJVSuKbysU9PHE4jhSjPKR+yVHcaY+CcCgYEA6gF7
3e5MByK6r3ZI7enDHrN4XoqtPh6PbmkGq/22LWFw2SeKD3nFTSIXQt+LopjR2Uwt
hAIwv+mvpLfQz59ud2fFhqkBokcf2pF179E9CCQLtM2vNeG3B/It6UE9QkDmGeGs
5hkfBJkXVJhRJl6aAuJjXE7lIvaxTb20gTFpzjkCgYAX0KRg1B8KT88FAxPNOX7o
6oldriqh6eaZCtbYi2DCLZggXDX1MP3BofDaMK415tXiw/eSlRmU2IcZA64iOWCc
3HPY81MAo6UMQLW2xeGXOq8BVYGkDjohDJ/qvxARzftMiXY5DewLK7nNIX0xWV+j
hlW1BDG6Nlv1MhzV319/CwKBgA+dO7uqS+5p9dUBaopdf8SLqyt7y2WKun1eirBt
RHuwtcv3pHG16WFlNfIjYnjeA5qhR6Q4VTJpEGxIS6me9MsI5JhArLg8ULbP3/O5
nX3ukc1lsBxDTGg+U6vty32hQPlXIqdT48r1wCXH6BpMU7B/lKuzI/z6Qwhx8Rpx
xqKZAoGBAJxwngBgwHMuDToAuypPgVx2Vpt5xbuY+Vwed+iiiV85OD4LzkO+yK08
C7mXTOAMzGWYpcEwx7JoxuV/SW45L5pMvoxVEtrVbwF3qAv/FiDivPW8Y8HNOQQb
/qjtTvKFOlajksvYvfZCZJo7nW/MVJE8qYBbNHtJOhMAHVXzZfeh
-----END RSA PRIVATE KEY-----

Solution

We have established that the messages are Base64 encoded and that they need to be converted back to their original encrypted files. Now we can perform decryption using one of the private keys. The following command is used to perform decryption using OpenSSL and RSA and it requires 3 variables.

openssl rsautl -decrypt -in $encrypted -out $output -inkey $privateKey

The $encrypted variable is used in the “-in” parameter for the input of the encrypted file. It expects a path to the encrypted file.

The $output variable is used in the “-out” parameter for the output for the decrypted file. It expects a path to a decrypted file that will be generated.

The $privateKey variable is used in the “-inkey” parameter for the input of the private key. It expects a path to the private key file.

Remember that we had 4 encrypted files and 10 private keys in total? We have to match the corresponding private key to the encrypted file. If we are dealing with a large amount of encrypted files and private keys I would create a for-loop to try each key with each encrypted file. OpenSSL will generate an error when I use an incorrect private key such as:

Attempting to decrypt an encrypted file with an invalid private key with OpenSSL
RSA operation error
7640:error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error:crypto\rsa\rsa_pk1.c:251:
7640:error:04065072:rsa routines:rsa_ossl_private_decrypt:padding check failed:crypto\rsa\rsa_ossl.c:491:

When OpenSSL doesn’t generate any errors then it managed to decrypt the encrypted file with the private key.

Successfully decrypted an encrypted file with the corresponding private key with OpenSSL
$encrypted = 'C:\Temp\encrypted1.bin'
$output = 'C:\Temp\output.file'
$privateKey = 'C:\Temp\key6.key'

openssl rsautl -decrypt -in $encrypted -out $output -inkey $privateKey

Upon checking the output.file as specified in the $output variable we can find that it contains a message upon opening in Notepad.

Opening the decrypted file in Notepad results in a message for the player

We got lucky that it’s a text file! Since we don’t have any information regarding the file extension we would have to perform some kind of content analysis or reading the file header to determine what kind of file we are dealing with. And there we have it! There are many different ways to go about this. I just like the simplicity of OpenSSL and PowerShell.

CategoriesSecurity

Creating a Certificate Signing Request (CSR) with multiple Subject Alternative Names (SAN) using OpenSSL – Wait, it’s all secure? Always has been.

Introduction

When you want to use digital certificates (also known als public key certificate) to establish a secure connection between computers, you will need to create a certificate signing request. A certificate is most commonly used for SSL/TLS, which is to provide confidentiality and integrity between two communicating applications.

The Subject Alternative Name (SAN or subjectAltName) is a field which allows you to define additional host names to be secured by a single certificate (also known as a Multi-Domain Certificate). For example, this can be useful when you have many domains/subdomains that needs to be secured. In terms of finances and pragmatism, you may not want to purchase different certificates as this might get expensive or having multiple certificates can be bothersome to implement.

You might be thinking, this sounds like a wildcard certificate! You’re not wrong as both type of certificates are quite similar. Both SAN and wildcard certificates allows you to secure multiple (sub)domains. However, a wildcard certificate cannot protect both identandy.com and identandy.org as the top-level domain (TLD) is different. A wildcard certificate only protects the primary domain (as defined in the Common Name) and any subdomains. Plus, wildcard certificates shouldn’t be used anymore since it’s deprecated as shown in section 7.2 of RFC 6125.

7.2. Wildcard Certificates This document states that the wildcard character ‘*’ SHOULD NOT be included in presented identifiers but MAY be checked by application clients (mainly for the sake of backward compatibility with deployed infrastructure).

Instructions

  1. Ensure that you have the latest version of OpenSSL installed.
  2. Create a new text file using your favorite simple text editor and name it request.config.
  3. Copy the following text to the request.config file and change the C\ST\L\O\OU\CN\DNS.* attributes accordingly. Go to chapter Definitions and Examples for more information regarding these attributes.

Syntax of a request.config file:

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = <countryName>
ST = <stateOrProvinceName>
L = <localityName>
O = <organizationName>
OU = <organizationalUnit>
CN = <commonName>
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = <hostName>
DNS.2 = <hostName>

Example of a request.config file:

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = NL
ST = Noord-Holland
L = Amsterdam
O = Identandy
OU = Public Relations
CN = identandy.com
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = identandy.com
DNS.2 = subdomain.identandy.com
DNS.3 = identandy.net
  1. Ensure that there aren’t any whitespaces at the beginning or the end of the lines.
  2. Start the following command to create the certificate signing request.

Syntax of an OpenSSL command to create a CSR:

openssl req -new -out <csr_file> -newkey rsa:2048 -nodes -sha256 -keyout <private_key> -config <request.config>

Example of an OpenSSL command to create a CSR:

openssl req -new -out identandy_com.csr -newkey rsa:2048 -nodes -sha256 -keyout identandy_com_private.key -config request.config
  1. After executing the OpenSSL command you will be greeted with the following message and your CSR (identandy_com.csr) and private key (identandy_com_private.key) have been created.
Generating a RSA private key
....+++++
......+++++
writing new private key to 'identandy_com_private.key'
-----
  1. Start the following command to verify the certificate signing request
openssl req -text -noout -verify -in identandy_com.csr

verify OK
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = NL, ST = Noord-Holland, L = Amsterdam, O = Identandy, OU = Public Relations, CN = identandy.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:ba:9e:94:bc:0b:36:35:18:3c:1d:f8:9b:34:47:
                    a6:a0:05:6c:18:29:06:f8:5e:e4:0a:45:42:4b:db:
                    58:1e:56:dd:c5:cb:7b:e1:c8:3c:0b:89:f8:9c:dd:
                    9c:5a:bd:9e:8b:7c:4b:5e:00:cb:71:02:9f:78:af:
                    d5:de:41:d2:7e:97:36:08:28:75:b1:ff:5b:ac:87:
                    17:d3:4b:23:7f:27:42:7c:34:f5:d9:58:94:b6:f4:
                    42:06:02:27:61:ea:54:09:d5:b9:31:b0:72:a2:17:
                    a4:95:61:3d:e7:81:2f:cc:cf:52:f0:e9:05:89:3b:
                    68:59:4f:17:21:58:d1:e5:e0:32:1c:03:cb:43:25:
                    60:1f:a3:b7:49:c3:07:d5:0a:77:9a:fc:d5:02:32:
                    d8:18:d9:84:9c:e1:69:cd:b4:d3:6a:3c:6c:43:0d:
                    22:29:1e:f9:07:58:e0:0b:50:d1:77:04:41:bd:7c:
                    45:c7:ad:45:15:3e:b6:48:d7:bc:9b:b1:56:32:2e:
                    02:23:7a:c9:20:6c:f5:10:87:f6:e2:b7:2b:6a:a6:
                    9b:a0:3c:2e:49:87:8c:89:37:5b:8e:cf:e4:06:1f:
                    8e:dc:90:71:78:9d:2c:2c:1c:bd:dc:db:a7:64:ac:
                    7d:a6:1a:d9:f7:cc:78:69:13:f6:7f:98:52:97:65:
                    a5:4f
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Key Usage:
                Key Encipherment, Data Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:identandy.com, DNS:subdomain.identandy.com, DNS:identandy.net
    Signature Algorithm: sha256WithRSAEncryption
         37:39:f8:4d:c2:71:c6:30:74:4f:de:dd:21:92:56:5e:55:bf:
         f4:80:cb:fa:0c:25:34:48:c5:be:77:5a:4e:f6:b7:3c:bf:40:
         8e:40:35:58:2a:e6:63:f6:5f:95:c8:bc:1b:c5:da:e2:d7:04:
         12:44:cd:0a:95:13:5b:87:a9:a4:d0:91:f8:d9:2f:e1:8e:a1:
         76:ea:60:cc:cd:a3:34:75:cb:ad:cd:f5:63:10:33:69:3a:fc:
         b4:4e:89:b8:e9:42:0b:af:62:4a:08:ac:0d:b8:fb:e1:3c:fe:
         ee:92:46:5e:e9:22:41:b0:68:93:a6:56:b1:6b:f4:c1:eb:54:
         a9:c9:5b:c7:e0:de:17:57:3e:79:90:eb:13:dd:12:c1:52:2c:
         75:e5:7f:13:73:8a:82:67:b2:66:3f:8a:fd:e6:04:4b:08:11:
         a2:b0:03:9f:cb:a8:41:fc:4a:ea:21:c7:1c:68:b9:65:6b:61:
         0a:b3:14:52:b5:c7:51:68:6f:d0:e8:f3:cf:cf:ff:af:27:7e:
         9b:ef:7a:10:ab:2e:48:4e:7a:49:4b:10:b7:6d:92:11:f2:e1:
         99:92:f1:c5:bc:6e:32:e7:d9:48:3a:66:f4:31:26:a2:e5:87:
         d9:de:39:0e:40:87:3c:b7:d3:e7:60:ca:9a:4f:1a:3d:f0:43:
         6f:32:f5:a5

And there you have it! That’s all you need to do to generate a CSR using OpenSSL. I hope that you have find it useful and if you have any questions leave a comment below.

Definitions and Examples

Confidentiality is the concept of the measures used to ensure the protection of the secrecy of data, objects, or resources. The goal of confidentiality protection is to prevent or minimize unauthorized access to data. Confidentiality focuses security measures on ensuring that no one other than the intended recipient of a message receives it or is able to read it. Confidentiality protection provides a means for authorized users to access and interact with resources, but it actively prevents unauthorized users from doing so. A wide range of security controls can provide protection for confidentiality, including, but not limited to, encryption, access controls, and steganography.

Integrity is the concept of protecting the reliability and correctness of data. Integrity protection prevents unauthorized alterations of data. It ensures that data remains correct, unaltered, and preserved. Properly implemented integrity protection provides a means for authorized changes while protecting against intended and malicious unauthorized activities (such as viruses and intrusions) as well as mistakes made by authorized users (such as mistakes and oversights).

Country Name (CN) Use the two-letter country code based on ISO 3166-1 alpha-2. Example: NL

State or Province (S) Spell out the state completely; do not abbreviate the state or province name. Example: Noord-Holland

Locality or City (L) Spell out the city or town name completely; do not abbreviate the locality or city name. Example: Amsterdam

Organization (O) If the company or department has an &, @, or any other symbol, the symbol must be spelled out or omitted. Example: XY & Z Corporation would be XYZ Corporation or XY and Z Corporation. 

Organizational Unit (OU)  The Organizational Unit (OU) field is the name of the department or organization unit making the request.

Common Name (CN) The Common Name (CN), also known as the Fully Qualified Domain Name (FQDN), is the characteristic value within a Distinguished Name. Example: identandy.com