### Install OpenSSL Gem from Source Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Instructions for cloning the OpenSSL gem repository from GitHub and installing it locally. ```bash git clone https://github.com/ruby/openssl.git cd openssl gem install ``` -------------------------------- ### Build and Install OpenSSL Source: https://github.com/ruby/openssl/blob/master/CONTRIBUTING.md Commands to configure, compile, and install OpenSSL with FIPS and tracing support enabled. ```bash $ ./Configure \ --prefix=$OPENSSL_DIR \ --libdir=lib \ enable-fips \ enable-trace \ '-Wl,-rpath,$(LIBRPATH)' \ -O0 -g3 -ggdb3 -gdwarf-5 $ make -j4 $ make install ``` -------------------------------- ### Generate RSA Keypairs Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkey.md Examples demonstrating RSA key generation with the default exponent and with a custom exponent. ```ruby # Generate 2048-bit RSA key with default exponent rsa = OpenSSL::PKey::RSA.generate(2048) # Generate with exponent 3 rsa = OpenSSL::PKey::RSA.generate(2048, 3) ``` -------------------------------- ### Complete Encryption Workflow Source: https://github.com/ruby/openssl/blob/master/_autodocs/cipher.md This example demonstrates a full encryption process using AES256. It includes key and IV generation, updating the cipher with data, and finalizing the encryption to get the complete ciphertext. ```ruby require 'openssl' cipher = OpenSSL::Cipher::AES256.new cipher.encrypt cipher.key = cipher.random_key cipher.iv = cipher.random_iv ciphertext = cipher.update('data') + cipher.final ``` -------------------------------- ### Verify OpenSSL Version Source: https://github.com/ruby/openssl/blob/master/CONTRIBUTING.md Command to print the version of the newly installed OpenSSL binary. ```bash $ $OPENSSL_DIR/bin/openssl version OpenSSL 3.2.0-alpha3-dev (Library: OpenSSL 3.2.0-alpha3-dev ) ``` -------------------------------- ### Secure Password-Based Encryption and Decryption Example Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkcs5.md A comprehensive example demonstrating secure encryption and decryption using OpenSSL::KDF for key derivation, AES-256-CBC for encryption, and proper handling of salt and IV. Ensure you have the 'openssl' gem required. ```ruby require 'openssl' # Encrypt password = 'user_password' salt = OpenSSL::Random.random_bytes(16) key = OpenSSL::KDF.pbkdf2_hmac( password, salt: salt, iterations: 100000, length: 32, hash: 'sha256' ) cipher = OpenSSL::Cipher.new('aes-256-cbc') cipher.encrypt cipher.key = key cipher.iv = cipher.random_iv plaintext = 'secret message' ciphertext = cipher.update(plaintext) + cipher.final # Storage format: salt + iv + ciphertext storage = [salt, cipher.iv, ciphertext].join('') # Decrypt stored = File.read('encrypted.bin') salt = stored[0...16] iv = stored[16...32] ciphertext = stored[32..-1] key = OpenSSL::KDF.pbkdf2_hmac( password, salt: salt, iterations: 100000, length: 32, hash: 'sha256' ) cipher = OpenSSL::Cipher.new('aes-256-cbc') cipher.decrypt cipher.key = key cipher.iv = iv plaintext = cipher.update(ciphertext) + cipher.final puts plaintext # => "secret message" ``` -------------------------------- ### Install OpenSSL Gem with Custom Directory Source: https://github.com/ruby/openssl/blob/master/README.md Install the openssl gem, specifying a custom directory for the OpenSSL library installation if needed. ```bash gem install openssl -- --with-openssl-dir=/opt/openssl ``` -------------------------------- ### Install OpenSSL Gem with Bundler Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Steps to add the OpenSSL gem to your project's Gemfile and install it using Bundler. ```bash echo "gem 'openssl'" >> Gemfile bundle install ``` -------------------------------- ### Example Usage of OpenSSL::PKCS5.pbkdf2_hmac_sha1 Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkcs5.md Demonstrates how to derive a key using the deprecated OpenSSL::PKCS5.pbkdf2_hmac_sha1 method. Ensure you have the 'openssl' gem required. ```ruby require 'openssl' password = 'secret_password' salt = OpenSSL::Random.random_bytes(16) key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(password, salt, 100000, 32) ``` -------------------------------- ### Example Usage of OpenSSL::PKCS5.pbkdf2_hmac Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkcs5.md Demonstrates how to derive a key using the deprecated OpenSSL::PKCS5.pbkdf2_hmac method. Ensure you have the 'openssl' gem required. ```ruby require 'openssl' password = 'my_password' salt = OpenSSL::Random.random_bytes(16) key = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, 100000, 32, 'sha256') ``` -------------------------------- ### OpenSSL Command Cipher Example Source: https://github.com/ruby/openssl/blob/master/_autodocs/configuration.md Example of how to specify a cipher when connecting to a server using the OpenSSL command-line tool. ```bash # OpenSSL command openssl s_client -connect example.com:443 -cipher 'ECDHE-RSA-AES256-GCM-SHA384' ``` -------------------------------- ### Generate EC Group and Convert Generator to BN Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkey.md Example showing how to create an EC group, get its generator point, and convert it to a BN representation. ```ruby require 'openssl' group = OpenSSL::PKey::EC::Group.new('prime256v1') point = group.generator bn = point.to_bn puts bn.to_s(16) # Hex representation ``` -------------------------------- ### Configure OpenSSL Environment Variables Source: https://github.com/ruby/openssl/blob/master/CONTRIBUTING.md Commands to retrieve the commit hash and set the installation directory for a custom OpenSSL build. ```bash $ git rev-parse --short HEAD 0bf18140f4 $ OPENSSL_DIR=$HOME/.openssl/openssl-fips-debug-0bf18140f4 ``` -------------------------------- ### Generate and Sign with DSA Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkey.md Example demonstrating the generation of a DSA keypair and signing a message digest. Note that syssign is deprecated. ```ruby require 'openssl' dsa = OpenSSL::PKey::DSA.generate(2048) digest = OpenSSL::Digest.digest('SHA1', 'message') sig = dsa.syssign(digest) ``` -------------------------------- ### Use Strong Key Derivation Parameters Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Example of using PBKDF2 with a high iteration count (100,000) for secure password-based key derivation. ```ruby # At least 100,000 iterations (more is better) key = OpenSSL::KDF.pbkdf2_hmac(password, salt: salt, iterations: 100000, ...) ``` -------------------------------- ### Run Ruby OpenSSL Test Suite Source: https://github.com/ruby/openssl/blob/master/CONTRIBUTING.md Commands to install dependencies and execute the test suite for the Ruby OpenSSL gem. ```bash $ bundle install # installs rake-compiler, test-unit, ... $ bundle exec rake compile $ bundle exec rake test ``` -------------------------------- ### Generate RSA Key and Extract Public Key Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkey.md Example showing RSA key generation and then extracting the public key component into a separate RSA object. ```ruby require 'openssl' rsa = OpenSSL::PKey::RSA.generate(2048) rsa_pub = rsa.public_key puts rsa_pub.private? # => false ``` -------------------------------- ### Generate DSA Key and Verify Signature Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkey.md Example demonstrating DSA key generation, signing, and verification. Note that sysverify is deprecated. ```ruby require 'openssl' dsa = OpenSSL::PKey::DSA.generate(2048) digest = OpenSSL::Digest.digest('SHA1', 'message') sig = dsa.syssign(digest) puts dsa.sysverify(digest, sig) # => true ``` -------------------------------- ### Create SSLContext with Default or Deprecated Protocol Source: https://github.com/ruby/openssl/blob/master/_autodocs/configuration.md Demonstrates creating an SSLContext instance. The first example uses the default constructor, while the second shows the deprecated method of specifying a protocol version. ```ruby require 'openssl' # Default context ctx = OpenSSL::SSL::SSLContext.new # With deprecated version specification ctx = OpenSSL::SSL::SSLContext.new(:TLSv1_2) ``` -------------------------------- ### Install Ruby OpenSSL Gem Source: https://github.com/ruby/openssl/blob/master/_autodocs/README.md Install the OpenSSL gem using the RubyGems package manager. This command is used to add the gem to your Ruby environment. ```bash gem install openssl ``` -------------------------------- ### OpenSSL::X509::ExtensionError Example Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md Illustrates catching an OpenSSL::X509::ExtensionError when attempting to create an invalid certificate extension using ExtensionFactory. ```ruby require 'openssl' begin factory = OpenSSL::X509::ExtensionFactory.new factory.create_extension([1, 2, 3]) # Too many elements rescue OpenSSL::X509::ExtensionError => e puts "Extension error: #{e.message}" end ``` -------------------------------- ### OpenSSL::SSL::SSLError Example Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md Demonstrates how to catch and handle OpenSSL::SSL::SSLError exceptions that may occur during TLS/SSL operations, such as establishing a connection. ```ruby require 'openssl' begin socket = OpenSSL::SSL::SSLSocket.open('example.com', 443) socket.connect rescue OpenSSL::SSL::SSLError => e puts "SSL error: #{e.message}" end ``` -------------------------------- ### Access OpenSSL Gem and Library Version Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Shows how to retrieve the installed OpenSSL gem version and the underlying OpenSSL library version at runtime. ```ruby require 'openssl' # Gem version puts OpenSSL::VERSION # => "4.0.2" # OpenSSL library version puts OpenSSL::OPENSSL_VERSION # => "OpenSSL 3.0.0 15 Sep 2021" # OpenSSL version number (hex) puts OpenSSL::OPENSSL_VERSION_NUMBER # => 0x30000000 ``` -------------------------------- ### Generate EC Key and Verify Signature Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkey.md Example of generating an EC keypair and verifying a signature using the deprecated dsa_verify_asn1 method. ```ruby require 'openssl' ec = OpenSSL::PKey::EC.generate('prime256v1') sig = ec.dsa_sign_asn1('message') puts ec.dsa_verify_asn1('message', sig) # => true ``` -------------------------------- ### Configure Minimum and Maximum TLS Versions Source: https://github.com/ruby/openssl/blob/master/_autodocs/configuration.md Sets the minimum and maximum TLS protocol versions allowed for an SSLContext. This example configures the context to use TLS 1.2 or higher. ```ruby require 'openssl' ctx = OpenSSL::SSL::SSLContext.new # Set to TLS 1.2 or higher ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION ctx.max_version = OpenSSL::SSL::TLS1_3_VERSION ``` -------------------------------- ### TLS/SSL Client Connection Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Establishes a secure TLS client connection to a remote host, performs a GET request, and reads the response. ```ruby require 'openssl' # Client connection ctx = OpenSSL::SSL::SSLContext.new ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER socket = OpenSSL::SSL::SSLSocket.open('example.com', 443, context: ctx) socket.connect socket.post_connection_check('example.com') # Read/write response = socket.write("GET / HTTP/1.0\r\n\r\n") data = socket.read(1024) socket.close ``` -------------------------------- ### Handle Incomplete RSA Key Error Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md This example shows catching an OpenSSL::PKey::PKeyError when performing an operation on an incomplete RSA key (e.g., before parameters are set). Requires 'openssl'. ```ruby require 'openssl' begin rsa = OpenSSL::PKey::RSA.new rsa.private_encrypt('data') # Incomplete RSA rescue OpenSSL::PKey::PKeyError => e puts "PKey error: #{e.message}" end ``` -------------------------------- ### Handle Unknown Digest Algorithm Error Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md This example demonstrates catching an OpenSSL::Digest::DigestError when an unsupported digest algorithm is specified. The 'openssl' gem must be required. ```ruby require 'openssl' begin OpenSSL::Digest.digest('NONEXISTENT', 'data') rescue OpenSSL::Digest::DigestError => e puts "Digest error: #{e.message}" end ``` -------------------------------- ### Generate Random IV for Cipher and Decryption Example Source: https://github.com/ruby/openssl/blob/master/_autodocs/cipher.md Demonstrates generating a random initialization vector (IV) for AES-128 in CBC mode and then using the generated key and IV to decrypt the ciphertext. ```ruby require 'openssl' cipher = OpenSSL::Cipher::AES128.new('CBC') cipher.encrypt key = cipher.random_key iv = cipher.random_iv # Returns 16 bytes for AES ciphertext = cipher.update('message') + cipher.final # Decryption decipher = OpenSSL::Cipher::AES128.new('CBC') decipher.decrypt decipher.key = key decipher.iv = iv plaintext = decipher.update(ciphertext) + decipher.final ``` -------------------------------- ### Generate EC Keys and Compute Shared Secret Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkey.md Example demonstrating the generation of two EC keypairs and computation of a shared secret using the deprecated dh_compute_key method. ```ruby require 'openssl' ec1 = OpenSSL::PKey::EC.generate('prime256v1') ec2 = OpenSSL::PKey::EC.generate('prime256v1') shared_secret = ec1.dh_compute_key(ec2.public_key) ``` -------------------------------- ### Set Default System Certificate Paths Source: https://github.com/ruby/openssl/blob/master/_autodocs/x509.md Initializes an X509 store and configures it to use the default system certificate paths. ```ruby require 'openssl' store = OpenSSL::X509::Store.new store.set_default_paths ``` -------------------------------- ### Handle Cipher Key Length Error Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md This example shows how to catch an OpenSSL::Cipher::CipherError that occurs due to an invalid (too short) cipher key length. It requires the 'openssl' gem. ```ruby require 'openssl' begin cipher = OpenSSL::Cipher.new('AES-256-CBC') cipher.encrypt cipher.key = 'short' # Too short rescue OpenSSL::Cipher::CipherError => e puts "Cipher error: #{e.message}" end ``` -------------------------------- ### Add Trusted CA Certificates from File Source: https://github.com/ruby/openssl/blob/master/_autodocs/x509.md Initializes an X509 store and adds trusted CA certificates from a specified PEM file. ```ruby require 'openssl' store = OpenSSL::X509::Store.new store.add_file('/etc/ssl/certs/ca-bundle.crt') ``` -------------------------------- ### Add Trusted CA Certificates from Directory Source: https://github.com/ruby/openssl/blob/master/_autodocs/x509.md Initializes an X509 store and adds trusted CA certificates from a directory. ```ruby require 'openssl' store = OpenSSL::X509::Store.new store.add_path('/etc/ssl/certs/') ``` -------------------------------- ### Verify Certificate Chain Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Shows how to set up an OpenSSL::X509::Store and verify a certificate chain. The actual verification call is commented out. ```ruby store = OpenSSL::X509::Store.new store.set_default_paths # store.verify(cert) ``` -------------------------------- ### SSLServer.new Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Initializes a new SSLServer instance, wrapping a TCPServer with SSL/TLS capabilities using the provided SSLContext. ```APIDOC ## SSLServer.new(tcp_server, context) ### Description Wraps a TCPServer with SSL/TLS. ### Parameters #### Path Parameters - **tcp_server** (TCPServer) - TCP server instance - **context** (SSLContext) - SSL context for connections ### Return Value SSLServer instance. ### Example ```ruby require 'openssl' require 'socket' ctx = OpenSSL::SSL::SSLContext.new ctx.cert = OpenSSL::X509::Certificate.new(File.read('cert.pem')) ctx.key = OpenSSL::PKey.read(File.read('key.pem')) tcp_server = TCPServer.new('localhost', 443) ssl_server = OpenSSL::SSL::SSLServer.new(tcp_server, ctx) ``` ``` -------------------------------- ### Require OpenSSL in Ruby Application Source: https://github.com/ruby/openssl/blob/master/README.md Include this line in your Ruby application to start using the OpenSSL functionalities. ```ruby require "openssl" ``` -------------------------------- ### Get SSLSocket Session Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Retrieves the current SSL/TLS session object. Returns nil if the session has not been established. ```ruby require 'openssl' socket = OpenSSL::SSL::SSLSocket.open('example.com', 443) socket.connect session = socket.session ``` -------------------------------- ### Configure Server Certificate and Key Source: https://github.com/ruby/openssl/blob/master/_autodocs/configuration.md Loads and assigns a server certificate and its corresponding private key to an SSLContext. The private key must match the certificate. ```ruby require 'openssl' cert = OpenSSL::X509::Certificate.new(File.read('server.crt')) key = OpenSSL::PKey::RSA.new(File.read('server.key')) ctx = OpenSSL::SSL::SSLContext.new ctx.cert = cert ctx.key = key ``` -------------------------------- ### Get Certificate Extensions Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Iterates through the extensions of an X.509 certificate and prints their Object Identifiers (OIDs) and values. ```ruby cert.extensions.each do |ext| puts "#{ext.oid}: #{ext.value}" end ``` -------------------------------- ### Create SSLSocket with Custom Context Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Demonstrates creating an SSLSocket with a custom SSLContext for peer verification. ```ruby ctx = OpenSSL::SSL::SSLContext.new ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER socket = OpenSSL::SSL::SSLSocket.open('example.com', 443, context: ctx) ``` -------------------------------- ### Dynamically Get Digest Class Source: https://github.com/ruby/openssl/blob/master/_autodocs/digest.md Retrieves a Digest subclass by its algorithm name. Useful for dynamic selection of hashing algorithms. ```ruby require 'openssl' # Get digest class dynamically md5_class = OpenSSL.Digest('MD5') digest = md5_class.new('test') puts digest.hexdigest # Error on unknown algorithm OpenSSL.Digest('Foo') # => NameError: wrong constant name Foo ``` -------------------------------- ### TLS/SSL Server Connection Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Sets up a basic TLS server that accepts incoming connections and handles them. ```ruby require 'openssl' require 'socket' cert = OpenSSL::X509::Certificate.new(File.read('cert.pem')) key = OpenSSL::PKey::RSA.new(File.read('key.pem')) ctx = OpenSSL::SSL::SSLContext.new ctx.cert = cert ctx.key = key tcp_server = TCPServer.new('0.0.0.0', 443) ssl_server = OpenSSL::SSL::SSLServer.new(tcp_server, ctx) loop do ssl_socket = ssl_server.accept # Handle connection ssl_socket.close end ``` -------------------------------- ### Generate EC Key and Sign Data Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkey.md Example of generating an EC keypair and signing data using the deprecated dsa_sign_asn1 method. ```ruby require 'openssl' ec = OpenSSL::PKey::EC.generate('prime256v1') sig = ec.dsa_sign_asn1('message') ``` -------------------------------- ### Get RSA Public Key Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkey.md Returns a new RSA instance containing only the public key components from an existing RSA keypair. ```ruby rsa_pub = rsa.public_key ``` -------------------------------- ### Configure HTTPS Client Context Source: https://github.com/ruby/openssl/blob/master/_autodocs/configuration.md Set up an SSL context for an HTTPS client, using sensible defaults or manual configuration for verification and certificate stores. ```ruby require 'openssl' ctx = OpenSSL::SSL::SSLContext.new ctx.set_params # Use sensible defaults # Or manually: ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER ctx.verify_hostname = true ctx.cert_store = OpenSSL::X509::Store.new ctx.cert_store.set_default_paths # Use with socket socket = OpenSSL::SSL::SSLSocket.open('example.com', 443, context: ctx) socket.connect socket.post_connection_check('example.com') ``` -------------------------------- ### Convert Extension to String Source: https://github.com/ruby/openssl/blob/master/_autodocs/x509.md Get the string representation of an X.509 extension in the format 'oid = critical, value'. This is useful for logging or display. ```ruby require 'openssl' ext = OpenSSL::X509::Extension.new('basicConstraints', 'CA:FALSE', true) puts ext.to_s # => "basicConstraints = critical, CA:FALSE" ``` -------------------------------- ### Modern Key Derivation with OpenSSL::KDF Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkcs5.md Demonstrates the recommended way to derive a key using OpenSSL::KDF.pbkdf2_hmac, which offers more flexible parameter passing. Ensure you have the 'openssl' gem required. ```ruby require 'openssl' password = 'my_password' salt = OpenSSL::Random.random_bytes(16) # Using OpenSSL::KDF (recommended) key = OpenSSL::KDF.pbkdf2_hmac( password, salt: salt, iterations: 100000, length: 32, hash: 'sha256' ) ``` -------------------------------- ### OpenSSL::X509::NameError Example Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md Shows how to handle OpenSSL::X509::NameError when parsing an invalid distinguished name string using parse_rfc2253. ```ruby require 'openssl' begin name = OpenSSL::X509::Name.parse_rfc2253('invalid dn string') rescue OpenSSL::X509::NameError => e puts "Name error: #{e.message}" end ``` -------------------------------- ### Apply Default SSLContext Parameters Source: https://github.com/ruby/openssl/blob/master/_autodocs/configuration.md Apply sensible defaults to an SSL context using the set_params method. These defaults include verification modes and options. ```ruby require 'openssl' ctx = OpenSSL::SSL::SSLContext.new ctx.set_params # Apply defaults ``` -------------------------------- ### OpenSSL::X509::Store#set_default_paths Source: https://github.com/ruby/openssl/blob/master/_autodocs/x509.md Adds default system certificate paths to the store. ```APIDOC ## OpenSSL::X509::Store#set_default_paths ### Description Adds default system certificate paths to the store. ### Method set_default_paths ### Request Example ```ruby require 'openssl' store = OpenSSL::X509::Store.new store.set_default_paths ``` ``` -------------------------------- ### Finalize Encryption/Decryption Source: https://github.com/ruby/openssl/blob/master/_autodocs/cipher.md Call `final()` after all `update()` calls to get the remaining encrypted or decrypted data. This method is essential for completing the cipher operation. ```ruby encrypted_data = cipher.final ``` -------------------------------- ### Get Base64 HMAC Value (Instance Method) Source: https://github.com/ruby/openssl/blob/master/_autodocs/hmac.md Returns the Base64-encoded HMAC value from an HMAC instance. Suitable for text-based data transmission. ```ruby require 'openssl' hmac = OpenSSL::HMAC.new('key', 'SHA256') hmac.update('test data') puts hmac.base64digest ``` -------------------------------- ### Asymmetric Cryptography with RSA Keypair Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Shows how to generate an RSA keypair, sign data with the private key, and verify the signature with the public key. ```ruby require 'openssl' # Generate RSA keypair rsa = OpenSSL::PKey::RSA.generate(2048) # Sign with private key data = 'message to sign' signature = rsa.sign_raw(nil, data) # Verify with public key is_valid = rsa.verify_raw(nil, signature, data) puts is_valid # => true ``` -------------------------------- ### Get Hexadecimal HMAC Value (Instance Method) Source: https://github.com/ruby/openssl/blob/master/_autodocs/hmac.md Returns the hex-encoded HMAC value from an HMAC instance. This is the final computed authentication code. ```ruby require 'openssl' hmac = OpenSSL::HMAC.new('key', 'SHA256') hmac << 'data to authenticate' puts hmac.hexdigest ``` -------------------------------- ### OpenSSL::Digest#initialize Source: https://github.com/ruby/openssl/blob/master/_autodocs/digest.md Creates a new Digest instance for a specified algorithm, optionally initializing it with data. ```APIDOC ## OpenSSL::Digest#initialize ### Description Creates a new Digest instance for the specified algorithm. Optionally, initial data can be provided to hash immediately. ### Method `OpenSSL::Digest::SHA256.new(data = nil)` ### Parameters #### Path Parameters - **data** (String) - Optional - Initial data to hash immediately. ### Response #### Success Response - **Digest instance** - A new instance of the Digest class. ### Example ```ruby require 'openssl' # Create digest and update incrementally digest = OpenSSL::Digest::SHA256.new digest << 'part1' digest << 'part2' result = digest.digest # Create with initial data digest2 = OpenSSL::Digest::SHA256.new('initial data') ``` ``` -------------------------------- ### Get Key Length for AES-256 Source: https://github.com/ruby/openssl/blob/master/_autodocs/cipher.md Retrieves the required key length in bytes for an AES-256 cipher instance. AES-256 requires a 32-byte key. ```ruby require 'openssl' cipher = OpenSSL::Cipher::AES256.new puts cipher.key_len # => 32 (256 bits / 8) ``` -------------------------------- ### Create SSLServer with Context Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Wraps a TCPServer with SSL/TLS using a provided SSLContext containing certificate and key. ```ruby require 'openssl' require 'socket' ctx = OpenSSL::SSL::SSLContext.new ctx.cert = OpenSSL::X509::Certificate.new(File.read('cert.pem')) ctx.key = OpenSSL::PKey.read(File.read('key.pem')) tcp_server = TCPServer.new('localhost', 443) ssl_server = OpenSSL::SSL::SSLServer.new(tcp_server, ctx) ``` -------------------------------- ### Validating Key Before Signing Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md Illustrates validating if a private key is available before attempting to sign data, preventing potential errors. ```ruby require 'openssl' # Validate before operations to prevent errors rsa = OpenSSL::PKey::RSA.generate(2048) if rsa.private? # Safe to sign sig = rsa.sign_raw(nil, 'data') else puts "Cannot sign: private key not available" end ``` -------------------------------- ### AES-128 Encryption and AES-256 with GCM Mode Source: https://github.com/ruby/openssl/blob/master/_autodocs/cipher.md Demonstrates initializing AES-128 for encryption and setting a random key and IV. Also shows initializing AES-256 with GCM mode. ```ruby require 'openssl' # AES-128 in CBC mode (default) cipher = OpenSSL::Cipher::AES128.new cipher.encrypt cipher.key = cipher.random_key cipher.iv = cipher.random_iv # Encrypt data ciphertext = cipher.update('Hello World') + cipher.final # With specific key size for AES cipher = OpenSSL::Cipher::AES256.new('GCM') ``` -------------------------------- ### Get Binary HMAC Value (Instance Method) Source: https://github.com/ruby/openssl/blob/master/_autodocs/hmac.md Returns the raw binary HMAC value from an HMAC instance. Use after updating the instance with all relevant data. ```ruby require 'openssl' hmac = OpenSSL::HMAC.new('key', 'SHA256') hmac << 'data' binary_code = hmac.digest ``` -------------------------------- ### SSLServer Attributes Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Provides read/write access to the `start_immediately` attribute, which determines whether the SSL handshake is performed automatically within the #accept method. The default value is true. ```APIDOC ## SSLServer Attributes ### Description Provides access to SSLServer properties. | Attribute | Type | Access | Description | |-----------|------|--------|-------------| | start_immediately | Boolean | read/write | Whether to perform SSL handshake in #accept (default: true) | ``` -------------------------------- ### Generate DH Parameters and Key Pair Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkey.md Generates a new DH instance with random parameters and a key pair. Use this for Diffie-Hellman key exchange setup. ```ruby require 'openssl' # Generate 2048-bit DH parameters with key pair dh = OpenSSL::PKey::DH.generate(2048) puts dh.p.to_s.length # Prime modulus puts dh.g.to_i # Generator puts dh.pub_key.to_s # Public key ``` -------------------------------- ### Handling OpenSSL::X509::StoreError Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md Demonstrates how to catch and handle OpenSSL::X509::StoreError when verifying a certificate. ```ruby require 'openssl' begin store = OpenSSL::X509::Store.new cert = OpenSSL::X509::Certificate.new(File.read('cert.pem')) store.verify(cert) rescue OpenSSL::X509::StoreError => e puts "Store error: #{e.message}" end ``` -------------------------------- ### Handling OpenSSL::KDF::KDFError Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md Demonstrates how to catch and handle OpenSSL::KDF::KDFError during key derivation. ```ruby require 'openssl' begin OpenSSL::KDF.pbkdf2_hmac('password', salt: '', iterations: 0) rescue OpenSSL::KDF::KDFError => e puts "KDF error: #{e.message}" end ``` -------------------------------- ### Get RSA Parameters Source: https://github.com/ruby/openssl/blob/master/_autodocs/pkey.md Retrieves all RSA parameters as a Hash. The hash contains keys for modulus, public exponent, private exponent, prime factors, and CRT exponents. ```ruby require 'openssl' rsa = OpenSSL::PKey::RSA.generate(2048) params = rsa.params puts params.keys # => ["n", "e", "d", "p", "q", "dmp1", "dmq1", "iqmp"] ``` -------------------------------- ### Prepare Cipher for Encryption Source: https://github.com/ruby/openssl/blob/master/_autodocs/cipher.md Initializes an AES-256 cipher and prepares it for encryption operations using the `encrypt` method. ```ruby require 'openssl' cipher = OpenSSL::Cipher::AES256.new cipher.encrypt ``` -------------------------------- ### Handle Invalid HMAC Digest Algorithm Error Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md This example shows how to catch an OpenSSL::HMAC::HMACError when an invalid digest algorithm is provided for HMAC. Ensure 'openssl' is required. ```ruby require 'openssl' begin hmac = OpenSSL::HMAC.new('key', 'BADDIGEST') rescue OpenSSL::HMAC::HMACError => e puts "HMAC error: #{e.message}" end ``` -------------------------------- ### Configure HTTPS Server Context Source: https://github.com/ruby/openssl/blob/master/_autodocs/configuration.md Set up an SSL context for an HTTPS server, including certificate and key loading, modern TLS versions, strong ciphers, and security options. ```ruby require 'openssl' require 'socket' cert = OpenSSL::X509::Certificate.new(File.read('cert.pem')) key = OpenSSL::PKey::RSA.new(File.read('key.pem')) ctx = OpenSSL::SSL::SSLContext.new ctx.cert = cert ctx.key = key # Modern TLS only ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION # Strong ciphers ctx.ciphers = 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256' # Security options ctx.options |= OpenSSL::SSL::OP_CIPHER_SERVER_PREFERENCE ctx.options |= OpenSSL::SSL::OP_NO_COMPRESSION tcp_server = TCPServer.new('0.0.0.0', 443) ssl_server = OpenSSL::SSL::SSLServer.new(tcp_server, ctx) ``` -------------------------------- ### Handle Invalid BN Base Error Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md This example demonstrates catching an OpenSSL::BN::BNError when attempting to create a Big Number with an invalid base. The 'openssl' gem must be required. ```ruby require 'openssl' begin bn = OpenSSL::BN.new('FF', 99) # Invalid base rescue OpenSSL::BN::BNError => e puts "BN error: #{e.message}" end ``` -------------------------------- ### OpenSSL::X509::Store#add_file Source: https://github.com/ruby/openssl/blob/master/_autodocs/x509.md Adds trusted CA certificates from a PEM file to the store. ```APIDOC ## OpenSSL::X509::Store#add_file ### Description Adds trusted CA certificates from a PEM file to the store. ### Method add_file ### Parameters #### Path Parameters - **path** (String) - Required - Path to PEM certificate file ### Request Example ```ruby require 'openssl' store = OpenSSL::X509::Store.new store.add_file('/etc/ssl/certs/ca-bundle.crt') ``` ``` -------------------------------- ### Accept SSLServer Connection Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Accepts a new SSL/TLS connection from a client, returning an SSLSocket for the accepted connection. Includes a loop for continuous client handling. ```ruby require 'openssl' require 'socket' ctx = OpenSSL::SSL::SSLContext.new ctx.cert = OpenSSL::X509::Certificate.new(File.read('cert.pem')) ctx.key = OpenSSL::PKey.read(File.read('key.pem')) tcp_server = TCPServer.new('localhost', 443) ssl_server = OpenSSL::SSL::SSLServer.new(tcp_server, ctx) loop do socket = ssl_server.accept puts "Client connected" # Handle socket... socket.close end ``` -------------------------------- ### Load X.509 Certificate Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Loads an X.509 certificate from a file. ```ruby require 'openssl' # Load certificate cert = OpenSSL::X509::Certificate.new(File.read('cert.pem')) ``` -------------------------------- ### Get IV Length for AES-128 CBC Source: https://github.com/ruby/openssl/blob/master/_autodocs/cipher.md Retrieves the required initialization vector (IV) length in bytes for an AES-128 cipher operating in CBC mode. AES typically uses a 16-byte IV. ```ruby require 'openssl' cipher = OpenSSL::Cipher::AES128.new('CBC') puts cipher.iv_len # => 16 ``` -------------------------------- ### Buffering Methods Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Illustrates IO-like buffering methods provided by OpenSSL::Buffering included in SSLSocket. ```ruby socket.read(n) # Read up to n bytes socket.write(data) # Write data socket.gets # Read a line socket.puts(data) # Write with newline socket.each_line # Iterate lines socket.readlines # Read all lines socket.sync # Synchronous mode flag ``` -------------------------------- ### Big Number Arithmetic and Operations Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Demonstrates creating Big Numbers (BN) and performing arithmetic, modular exponentiation, and primality testing. ```ruby require 'openssl' # Create BNs a = OpenSSL::BN.new(12345) b = OpenSSL::BN.new(67890) # Arithmetic sum = a + b product = a * b quotient = a / b remainder = a % b # Modular operations mod = OpenSSL::BN.new(1000) result = a.mod_exp(b, mod) # Primality testing p = OpenSSL::BN.rand(256, 1) puts p.prime? # Probabilistic test ``` -------------------------------- ### HMAC Generation and Verification Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Demonstrates generating and verifying HMACs using SHA256. Includes a note on using constant-time comparison for security. ```ruby require 'openssl' # Generate HMAC key = 'secret_key' hmac = OpenSSL::HMAC.hexdigest('SHA256', key, 'message') # Verify HMAC computed = OpenSSL::HMAC.hexdigest('SHA256', key, 'message') is_valid = (computed == hmac) # Vulnerable to timing attacks! # Use constant-time comparison hmac1 = OpenSSL::HMAC.digest('SHA256', key, 'data1') hmac2 = OpenSSL::HMAC.digest('SHA256', key, 'data1') is_equal = OpenSSL::HMAC.new(key, 'SHA256').tap { |h| h << 'data1' } == OpenSSL::HMAC.new(key, 'SHA256').tap { |h| h << 'data1' } ``` -------------------------------- ### Password-Based Key Derivation (PBKDF2) Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Shows how to derive a cryptographic key from a password using PBKDF2 with SHA-256, including salt and iteration count. ```ruby require 'openssl' password = 'user_password' salt = OpenSSL::Random.random_bytes(16) # PBKDF2 with SHA-256 key = OpenSSL::KDF.pbkdf2_hmac( password, salt: salt, iterations: 100000, length: 32, hash: 'sha256' ) ``` -------------------------------- ### Configure SNI Callback Source: https://github.com/ruby/openssl/blob/master/_autodocs/configuration.md Set up a server name indication (SNI) callback to select the appropriate SSL context based on the requested hostname. ```ruby require 'openssl' # Context mapping contexts = { 'example.com' => ctx_example, 'test.com' => ctx_test, } default_ctx = OpenSSL::SSL::SSLContext.new default_ctx.servername_cb = proc do |ssl, hostname| contexts[hostname] || default_ctx end ``` -------------------------------- ### Catching Specific OpenSSL Errors Source: https://github.com/ruby/openssl/blob/master/_autodocs/errors.md Shows how to use begin-rescue blocks to catch specific OpenSSL errors like CertificateError and StoreError, falling back to a general OpenSSLError. ```ruby require 'openssl' # Catch specific errors begin cert = OpenSSL::X509::Certificate.new(cert_data) store = OpenSSL::X509::Store.new store.verify(cert) rescue OpenSSL::X509::CertificateError => e puts "Invalid certificate: #{e.message}" rescue OpenSSL::X509::StoreError => e puts "Verification failed: #{e.message}" rescue OpenSSL::OpenSSLError => e puts "OpenSSL error: #{e.message}" end ``` -------------------------------- ### Connect SSLSocket Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Initiates the TLS handshake to establish an SSL/TLS connection. Throws OpenSSL::SSL::SSLError on handshake failure. ```ruby require 'openssl' socket = OpenSSL::SSL::SSLSocket.open('example.com', 443) socket.connect puts "Connected!" ``` -------------------------------- ### Clone OpenSSL Source Source: https://github.com/ruby/openssl/blob/master/CONTRIBUTING.md Commands to clone the OpenSSL repository from GitHub. ```bash $ git clone https://github.com/openssl/openssl.git $ cd openssl ``` -------------------------------- ### SSLServer#accept Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Accepts a new incoming SSL/TLS connection from a client and returns an SSLSocket object representing that connection. ```APIDOC ## SSLServer#accept ### Description Accepts a new SSL/TLS connection from a client. ### Method `ssl_socket = server.accept` ### Return Value SSLSocket for the accepted connection. ### Example ```ruby require 'openssl' require 'socket' ctx = OpenSSL::SSL::SSLContext.new ctx.cert = OpenSSL::X509::Certificate.new(File.read('cert.pem')) ctx.key = OpenSSL::PKey.read(File.read('key.pem')) tcp_server = TCPServer.new('localhost', 443) ssl_server = OpenSSL::SSL::SSLServer.new(tcp_server, ctx) loop do socket = ssl_server.accept puts "Client connected" # Handle socket... socket.close end ``` ``` -------------------------------- ### Inspect Certificate Properties Source: https://github.com/ruby/openssl/blob/master/_autodocs/overview.md Demonstrates how to access various properties of an X.509 certificate object in Ruby. ```ruby puts cert.subject puts cert.issuer puts cert.serial puts cert.not_before puts cert.not_after puts cert.public_key.class ``` -------------------------------- ### Prepare Cipher for Decryption Source: https://github.com/ruby/openssl/blob/master/_autodocs/cipher.md Initializes an AES-256 cipher and prepares it for decryption operations using the `decrypt` method. ```ruby require 'openssl' cipher = OpenSSL::Cipher::AES256.new cipher.decrypt ``` -------------------------------- ### OpenSSL::X509::Store#add_path Source: https://github.com/ruby/openssl/blob/master/_autodocs/x509.md Adds trusted CA certificates from a directory to the store. ```APIDOC ## OpenSSL::X509::Store#add_path ### Description Adds trusted CA certificates from a directory to the store. ### Method add_path ### Parameters #### Path Parameters - **path** (String) - Required - Directory path containing certificates ### Request Example ```ruby require 'openssl' store = OpenSSL::X509::Store.new store.add_path('/etc/ssl/certs/') ``` ``` -------------------------------- ### SSLSocket#connect Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Initiates the TLS handshake and establishes the SSL/TLS connection for an SSLSocket. It can throw OpenSSL::SSL::SSLError on handshake failure. ```APIDOC ## SSLSocket#connect ### Description Initiates the TLS handshake and establishes the SSL/TLS connection. ### Method `socket.connect` ### Throws OpenSSL::SSL::SSLError on handshake failure. ### Example ```ruby require 'openssl' socket = OpenSSL::SSL::SSLSocket.open('example.com', 443) socket.connect puts "Connected!" ``` ``` -------------------------------- ### Configure SSLContext Attributes Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Configures various attributes of an SSL context, including certificates, keys, verification settings, and TLS versions. Requires certificate and key files for server-side configurations. ```ruby require 'openssl' ctx = OpenSSL::SSL::SSLContext.new ctx.cert = OpenSSL::X509::Certificate.new(File.read('cert.pem')) ctx.key = OpenSSL::PKey.read(File.read('key.pem')) ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER ctx.cert_store = OpenSSL::X509::Store.new ctx.cert_store.add_file('/etc/ssl/certs/ca-bundle.crt') ``` -------------------------------- ### Load and Inspect X509 Request Source: https://github.com/ruby/openssl/blob/master/_autodocs/x509.md Loads an X.509 request from a PEM file and prints its subject and public key class. ```ruby require 'openssl' req = OpenSSL::X509::Request.new(File.read('request.pem')) puts req.subject puts req.public_key.class ``` -------------------------------- ### Generate Encryption Key using PBKDF2 Source: https://github.com/ruby/openssl/blob/master/_autodocs/configuration.md Configure key derivation for password-based encryption using PBKDF2 with specified salt, iterations, key length, and digest algorithm. ```ruby require 'openssl' # Key derivation configuration password = 'user_password' salt = OpenSSL::Random.random_bytes(16) iterations = 100000 # Minimum recommended; more is better key_length = 32 # 256 bits for AES-256 digest = 'sha256' key = OpenSSL::KDF.pbkdf2_hmac( password, salt: salt, iterations: iterations, length: key_length, hash: digest ) ``` -------------------------------- ### Load and Inspect X.509 Certificate Source: https://github.com/ruby/openssl/blob/master/_autodocs/x509.md Loads an X.509 certificate from a PEM file and prints its subject, issuer, validity period, and public key type. Requires the 'openssl' library and a 'cert.pem' file. ```ruby require 'openssl' cert = OpenSSL::X509::Certificate.new(File.read('cert.pem')) puts cert.subject puts cert.issuer puts cert.not_before puts cert.not_after puts cert.public_key.class ``` -------------------------------- ### Create New SSLContext Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Creates a new SSL context. The protocol version can be specified optionally. Legacy version specification is deprecated. ```ruby require 'openssl' # Create basic context ctx = OpenSSL::SSL::SSLContext.new # Legacy version specification (deprecated) ctx = OpenSSL::SSL::SSLContext.new(:TLSv1_2) ``` -------------------------------- ### Set SSLContext Parameters Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Sets optimized defaults for HTTP-like protocols by merging default parameters with provided ones. Useful for configuring verification modes, options, and TLS versions. ```ruby require 'openssl' ctx = OpenSSL::SSL::SSLContext.new ctx.set_params(verify_mode: OpenSSL::SSL::VERIFY_NONE) # Override defaults ctx = OpenSSL::SSL::SSLContext.new ctx.set_params({ verify_mode: OpenSSL::SSL::VERIFY_PEER, cert_store: OpenSSL::X509::Store.new, min_version: OpenSSL::SSL::TLS1_2_VERSION }) ``` -------------------------------- ### OpenSSL::HMAC.new Source: https://github.com/ruby/openssl/blob/master/_autodocs/hmac.md Creates a new HMAC instance for incremental computation. ```APIDOC ## OpenSSL::HMAC.new ### Description Creates a new HMAC instance. ### Method `OpenSSL::HMAC.new(key, digest_algorithm)` ### Parameters #### Path Parameters - **key** (String) - Required - Secret key for HMAC computation - **digest_algorithm** (String, OpenSSL::Digest) - Required - Digest algorithm or instance ### Response #### Success Response - **return value** (HMAC instance) - HMAC instance. ### Request Example ```ruby require 'openssl' hmac = OpenSSL::HMAC.new('secret_key', 'SHA256') hmac << 'part1' hmac << 'part2' result = hmac.digest ``` ``` -------------------------------- ### OpenSSL::SSL::SSLContext.new Source: https://github.com/ruby/openssl/blob/master/_autodocs/ssl.md Creates a new SSL context with optional protocol version specification. The 'version' parameter is deprecated in favor of 'min_version' and 'max_version'. ```APIDOC ## OpenSSL::SSL::SSLContext.new ### Description Creates a new SSL context with optional protocol version specification. ### Method `OpenSSL::SSL::SSLContext.new(version = nil)` ### Parameters #### Path Parameters - **version** (Symbol, String) - Optional - Protocol version (deprecated; use min_version/max_version instead) ### Return Value SSLContext instance. ### Example ```ruby require 'openssl' # Create basic context ctx = OpenSSL::SSL::SSLContext.new # Legacy version specification (deprecated) ctx = OpenSSL::SSL::SSLContext.new(:TLSv1_2) ``` ``` -------------------------------- ### Create X.509 Extension using a String Specification Source: https://github.com/ruby/openssl/blob/master/_autodocs/x509.md Create a certificate extension from a string formatted as 'oid = critical, value'. This is a concise way to define extensions. ```ruby require 'openssl' factory = OpenSSL::X509::ExtensionFactory.new ext = factory.create_extension('subjectAltName = DNS:example.com, DNS:www.example.com') ``` -------------------------------- ### Verify OpenSSL FIPS Providers Source: https://github.com/ruby/openssl/blob/master/CONTRIBUTING.md Lists active OpenSSL providers to confirm that base and fips providers are correctly loaded. ```bash $ OPENSSL_CONF=$OPENSSL_DIR/ssl/openssl_fips.cnf \ $OPENSSL_DIR/bin/openssl list -providers ``` -------------------------------- ### Generate Random Key for Cipher Source: https://github.com/ruby/openssl/blob/master/_autodocs/cipher.md Shows how to generate a random encryption key for a cipher instance after preparing it for encryption. The key length is appropriate for the chosen cipher (e.g., 32 bytes for AES-256). ```ruby require 'openssl' cipher = OpenSSL::Cipher::AES256.new cipher.encrypt key = cipher.random_key # Returns 32 bytes for AES-256 cipher.iv = cipher.random_iv ciphertext = cipher.update('secret data') + cipher.final ``` -------------------------------- ### Pretty Print BN Instance Source: https://github.com/ruby/openssl/blob/master/_autodocs/bn.md Provides a pretty-printed representation of a BN instance for inspection, typically used with the `pp` method. ```ruby require 'openssl' require 'pp' bn = OpenSSL::BN.new(12345) pp bn # Outputs: # ``` -------------------------------- ### Build and push gem (for older branches) Source: https://github.com/ruby/openssl/wiki/How-to-maintain-Ruby-OpenSSL Manually build the gem from the gemspec and push it to rubygems.org. This step is specifically for branches up to version 3.1. ```shell gem build openssl.gemspec gem push openssl-3.1.2.gem ``` -------------------------------- ### OpenSSL::PKey::PKey Source: https://github.com/ruby/openssl/blob/master/_autodocs/types.md Base class for all public key types. ```APIDOC ## Class OpenSSL::PKey::PKey ### Description Base class for all public key types. ### Common Methods - sign_raw(algorithm, data, options) - Sign data - verify_raw(algorithm, signature, data) - Verify signature - encrypt(data, options) - Encrypt with public key - decrypt(data) - Decrypt with private key - derive(peer_key, options) - Compute shared secret - private? - Check if private key is present - public_to_pem, public_to_der - Export public key - to_pem, to_der - Export full key ### Source `ext/openssl/ossl_pkey.c` ```