Lua
Lua
SSH HSM Public Key Authentication
See more SSH Examples
Demonstrates SSH public-key authentication using a private key stored on an HSM — a USB token or smart card — accessed through PKCS#11. A session is opened with the vendor's driver, the key handles are located, and an SshKey object is bound to them with UsePkcs11.
Background: The point of an HSM is that the private key is generated on the device and cannot be exported: the signing operation happens on the hardware, so the key material never reaches your application's memory or disk. Even a fully compromised host cannot yield a copy of the key. PKCS#11 is the vendor-neutral interface to such devices, which is why the driver path and the object-finding template are the only vendor-specific parts of this example.
Chilkat Lua Downloads
local chilkat = require("chilkat")
-- This example requires the Chilkat API to have been previously unlocked.
-- See Global Unlock Sample for sample code.
-- Demonstrates SSH public-key authentication using a private key stored on an HSM (a USB token
-- or smart card) accessed through PKCS#11.
--
-- Note: Chilkat's PKCS#11 implementation runs on Windows, Linux, macOS, and other supported
-- operating systems.
local pkcs11 = chilkat.Pkcs11.new()
-- The PKCS#11 driver supplied by your HSM vendor: a .dll on Windows, a .so on Linux, or a
-- .dylib on macOS.
pkcs11.shared_lib_path = "C:/Program Files (x86)/Gemalto/IDGo 800 PKCS#11/IDPrimePKCS1164.dll"
-- The PIN should come from a secure source rather than being hard-coded.
local pin = "0000"
-- Normal user = 1
local userType = 1
local success = pkcs11:quick_session(userType, pin)
if not success then
print(pkcs11.last_error_text)
return
end
-- Describe the private key object to be located on the HSM.
local json = chilkat.JsonObject.new()
json:update_string("class", "private_key")
json:update_string("label", "MySshKey")
local priv_handle = pkcs11:find_object(json)
if priv_handle == 0 then
print(pkcs11.last_error_text)
return
end
-- Find the corresponding public key by changing the class in the same template.
json:update_string("class", "public_key")
local pub_handle = pkcs11:find_object(json)
if pub_handle == 0 then
print(pkcs11.last_error_text)
return
end
-- Create an SSH key object that uses the HSM handles. The key type may be "rsa" or "ec".
local key = chilkat.SshKey.new()
local keyType = "rsa"
success = key:use_pkcs11(pkcs11, priv_handle, pub_handle, keyType)
if not success then
print(key.last_error_text)
return
end
local ssh = chilkat.Ssh.new()
local port = 22
success = ssh:connect("ssh.example.com", port)
if not success then
print(ssh.last_error_text)
return
end
-- The corresponding public key must already be installed on the SSH server for the account.
-- The signing operation happens on the HSM -- the private key never leaves the device.
success = ssh:authenticate_pk("mySshLogin", key)
if not success then
print(ssh.last_error_text)
return
end
print("Public-key authentication successful.")
ssh:disconnect()
pkcs11:logout()
pkcs11:close_session()