PureBasic
PureBasic
RSA Decrypt using Private Key on Smartcard or USB Token via Apple Keychain
See more Apple Keychain Examples
RSA decryption using a certificate's private key located on a hardware token or smartcard via the Apple Keychain.Note: This example requires Chilkat v10.1.2 or greater.
Chilkat PureBasic Downloads
IncludeFile "CkBinData.pb"
IncludeFile "CkCert.pb"
IncludeFile "CkRsa.pb"
Procedure ChilkatExample()
success.i = 0
; Beforehand, we generated a 256-bit AES key, RSA encrypted, and saved to a file as in this example:
; Generate a Random 256-bit AES Key and RSA Encrypt
; The RSA public key used to encrypt in the above example was obtained from the Apple Keychain
; like this:
; Export a Public Key from USB Token or Smartcard using the Apple Keychain
; This example will load the encrypted data and will RSA decrypt using the
; private key of a certificate on a USB token (or smart card) via the Keychain.
; You can list the Keychain certificates on hardware tokens using the following example:
; Apple Keychain - List Certs on Smartcards and USB Tokens
; Get the RSA encrypted data to be decrypted.
bd.i = CkBinData::ckCreate()
If bd.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; In all Chilkat methods expecting a path, you can pass either absolute or relative paths.
success = CkBinData::ckLoadFile(bd,"rsaEncrypted/myAes.key")
If success = 0
Debug "Failed to load the encrypted AES key."
CkBinData::ckDispose(bd)
ProcedureReturn
EndIf
; Load the certificate having the private key from the Apple Keychain
; On MacOS and iOS, the LoadByCommonName function will search the Apple Keychain for the matching certificate.
cert.i = CkCert::ckCreate()
If cert.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; To potentially prevent the PIN dialog from being displayed,
; we'll need to provide the USB token (or smart card) PIN
; Note: It might not be possible to prevent the PIN dialog from being displayed
;
CkCert::setCkSmartCardPin(cert, "123456")
success = CkCert::ckLoadByCommonName(cert,"Test 2048 bit RSA")
If success = 0
Debug CkCert::ckLastErrorText(cert)
CkBinData::ckDispose(bd)
CkCert::ckDispose(cert)
ProcedureReturn
EndIf
rsa.i = CkRsa::ckCreate()
If rsa.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; Specify we wish to use the certificate's private key for decryption.
success = CkRsa::ckSetX509Cert(rsa,cert,1)
If success = 0
Debug CkRsa::ckLastErrorText(rsa)
CkBinData::ckDispose(bd)
CkCert::ckDispose(cert)
CkRsa::ckDispose(rsa)
ProcedureReturn
EndIf
; RSA Decrypt
CkRsa::setCkVerboseLogging(rsa, 1)
success = CkRsa::ckDecryptBd(rsa,bd,1)
If success = 0
Debug CkRsa::ckLastErrorText(rsa)
CkBinData::ckDispose(bd)
CkCert::ckDispose(cert)
CkRsa::ckDispose(rsa)
ProcedureReturn
EndIf
; The contents of bd are now decrypted.
Debug "Num bytes after decryption: " + Str(CkBinData::ckNumBytes(bd))
; Some additional notes:
;
; If using a Yubikey token, the certificate must be installed in the Key Management slot.
; The Digital Signature slot is for RSA keys to be used for signing,
; and the Key Management slot is for RSA keys to be used for decrypting.
;
; If you try to use the RSA key from the Digital Signature slot, you'll get an error such as this:
; The operation couldn't be completed.
; (OSStatus error -50 - algid:encrypt:RSA:PKCS1: algorithm not supported by the key
; <SecKeyRef:('com.apple.pivtoken:AF7172EB60DDCBF1D28459AE24398E11') 0x600001ecca90>)
CkBinData::ckDispose(bd)
CkCert::ckDispose(cert)
CkRsa::ckDispose(rsa)
ProcedureReturn
EndProcedure