Categories

J&S-Soft Overview

J&S-Soft GmbH, based in Heidelberg, is an international consulting and software development company specializing in technologies such as SAP HANA, SAP Business Technology Platform (BTP), S/4HANA, as well as SAP UI5 and SAP Fiori. In addition to these services, J&S-Soft GmbH develops its own software solutions, including the open-source framework enmeshed. This framework enables simple, intelligent, and secure GDPR-compliant data transfers, even extending to private users.

Since its founding, the company has established numerous partnerships, leading to continuous revenue growth. Notably, in 2023, J&S-Soft GmbH generated 40% of its revenue from products related to the enmeshed framework. Continued strong revenue growth is expected for 2024. To maintain this success, the further development of the enmeshed framework is of great importance.

CEP SoSe24 Project Overview

Objectives

With the planned project “CEP SoSe24,” J&S-Soft GmbH aims to achieve the following objectives:

  1. Significant Advancement of the Enmeshed Framework
    • Enhance and expand the existing capabilities of the enmeshed framework to support more robust and scalable applications.
  2. Secure Generation and Management of Multiple Keys for Various Cryptographic Applications
    • Develop and implement mechanisms to securely generate and manage numerous keys essential for different cryptographic procedures.
  3. Increase Compatibility through the Integration of Various Hardware Security Modules
    • Improve the compatibility of the enmeshed framework by integrating different hardware security modules (HSMs) to enhance security and performance.
  4. Evaluation of Previous Developments and Incorporation of New Ideas into the Enmeshed Framework
    • Assess the current developments and integrate new concepts and innovations to continuously improve the enmeshed framework.

Project-Specific Conditions

The following chapters describe the conditions specific to the project.

Organizational Conditions

The development team at J&S-Soft GmbH employs various encryption methods within the enmeshed framework for secure communication and data exchange. In this context, a multitude of keys is generated and managed. A significant challenge is to generate these keys securely and protect them from unauthorized access. To adequately address this risk, the process will be secured using different Hardware Security Modules (HSMs) in the future.

Project Work Packages

The project is divided into three work packages:

AP-1: Conceptualization of Secure Key Management Using Hardware Security Modules

Develop a comprehensive concept for secure key management utilizing HSMs to enhance security and efficiency.

AP-2: Implementation Based on the Developed Concept

Execute the implementation of the secure key management system according to the conceptual framework established in AP-1.

AP-3: Creation of a Risk Assessment for the Developed Implementation

Conduct a thorough risk assessment of the implemented key management system to identify potential vulnerabilities and ensure robust security measures are in place.

Crypto Layer

The Crypto Layer is a comprehensive and flexible cryptographic library designed to provide a unified interface for various cryptographic operations and algorithms. It offers a wide range of functionalities, including encryption, decryption, signing, signature verification, and hashing, while supporting both symmetric and asymmetric cryptography.

Features

  • Encryption Algorithms: Supports a variety of encryption algorithms, including:

    • Asymmetric Encryption: RSA, ECC (Elliptic Curve Cryptography) with various curve types (P-256, P-384, P-521, secp256k1, Brainpool curves, Curve25519, Curve448, FRP256v1)
    • Symmetric Block Ciphers: AES (with multiple modes like GCM, CCM, ECB, CBC, CFB, OFB, CTR), Triple DES (two-key and three-key configurations), DES, RC2, Camellia
    • Stream Ciphers: RC4, ChaCha20
  • Hashing Algorithms: Supports a wide range of hashing algorithms, including:

    • SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256)
    • SHA-3 (SHA3-224, SHA3-256, SHA3-384, SHA3-512)
    • MD2, MD4, MD5, RIPEMD-160
  • Key Management: Provides a unified interface for creating, loading, and managing cryptographic keys, supporting various key usages and algorithms.

  • Cross-Platform Support: Designed to work seamlessly across multiple platforms, including Linux and Windows, with platform-specific implementations for key handling and security module integration.

  • Security Module Integration: Integrates with Hardware Security Modules (HSMs) and Trusted Platform Modules (TPMs) for secure key storage and cryptographic operations, ensuring enhanced security and compliance with industry standards.

  • Extensibility: The modular design of the Crypto Layer allows for easy extension and integration of additional cryptographic algorithms and security modules in the future.

Usage

The Crypto Layer provides a comprehensive set of interfaces and enums for working with cryptographic operations and algorithms. Here’s a brief overview of the main components:

Encryption Algorithms

The encryption module defines enums for various encryption algorithms, including:

  • AsymmetricEncryption: Represents asymmetric encryption algorithms like RSA and ECC.
  • BlockCiphers: Represents symmetric block cipher algorithms like AES, Triple DES, DES, RC2, and Camellia.
  • StreamCiphers: Represents stream cipher algorithms like RC4 and ChaCha20.

Hashing Algorithms

The hashes module defines the Hash enum, which represents various hashing algorithms like SHA-1, SHA-2, SHA-3, MD2, MD4, MD5, and RIPEMD-160.

Key Management

The key_handle module provides the KeyHandle trait, which defines a common interface for cryptographic key operations like signing, decryption, encryption, and signature verification. The GenericKeyHandle enum represents a platform-agnostic key handle that can be used on both Linux and Windows platforms.

Security Module Integration

The module_provider module defines the Provider trait, which encapsulates operations related to cryptographic processing and key management. This trait is designed to be implemented by security modules, ensuring a unified approach to interacting with different types of security modules.

The factory module provides the SecModules struct, which serves as a namespace for managing and accessing security module instances. It includes methods for retrieving or creating instances of security modules based on their type (HSM or TPM).

Error Handling

The error module defines the SecurityModuleError enum, which represents various types of errors that can occur within a security module, including errors originating from HSMs, TPMs, or during cryptographic operations like signing, decryption, encryption, and signature verification.

Usage Examples

Here are some usage examples based on the Windows TPM handler implementation:

Creating a TPM Provider

use crypto_layer::factory::{SecModules, SecurityModule};
use crypto_layer::tpm::core::instance::TpmType;

let key_id = "my_key_id".to_string();
let tpm_provider = SecModules::get_instances(key_id, SecurityModule::Tpm(TpmType::default()))
    .expect("Failed to create TPM provider");

Initializing the TPM Module

use crypto_layer::common::error::SecurityModuleError;

match tpm_provider.lock().unwrap().initialize_module() {
    Ok(()) => println!("TPM module initialized successfully"),
    Err(e) => println!("Failed to initialize TPM module: {:?}", e),
}

Creating a Key

use crypto_layer::common::crypto::algorithms::{
    encryption::{AsymmetricEncryption, BlockCiphers},
    hashes::Hash,
};
use crypto_layer::common::KeyUsage;

let key_algorithm = AsymmetricEncryption::Ecc(EccSchemeAlgorithm::EcDsa(EccCurves::P256));
let sym_algorithm = Some(BlockCiphers::Aes(SymmetricMode::Cbc, KeyBits::Bits256));
let hash = Some(Hash::Sha2(Sha2Bits::Sha256));
let key_usages = vec![KeyUsage::SignEncrypt, KeyUsage::Decrypt];

match tpm_provider.lock().unwrap().create_key(
    "my_key_id",
    key_algorithm,
    sym_algorithm,
    hash,
    key_usages,
) {
    Ok(()) => println!("Key created successfully"),
    Err(e) => println!("Failed to create key: {:?}", e),
}

Signing Data

let data = b"Hello, world!";

match tpm_provider.lock().unwrap().sign_data(data) {
    Ok(signature) => println!("Signature: {:?}", signature),
    Err(e) => println!("Failed to sign data: {:?}", e),
}

Verifying Signature

let data = b"Hello, world!";
let signature = // ... obtained signature ...

match tpm_provider.lock().unwrap().verify_signature(data, &signature) {
    Ok(valid) => {
        if valid {
            println!("Signature is valid");
        } else {
            println!("Signature is invalid");
        }
    }
    Err(e) => println!("Failed to verify signature: {:?}", e),
}

These examples demonstrate how to use the Windows TPM handler implementation to perform various cryptographic operations using the Crypto Layer.

Installation

The Crypto Layer is distributed as a Rust crate and can be included in your project by adding the following line to your Cargo.toml file:

[dependencies]
crypto-layer = "0.1.0"

Contributing

Contributions to the Crypto Layer are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the project’s GitHub repository.

License

The Crypto Layer is released under the MIT License.

YubiKey Provider Documentation

Overview

This module provides cryptographic operations using a YubiKey. It implements the Provider trait and interacts with the YubiKey device for key management and cryptographic operations.

Table of Contents

  1. Dependencies
  2. Constants
  3. Provider Implementation
  4. Helper Functions
  5. License

Cryptographic Operations Test Documentation

This document provides a comprehensive overview of the test cases designed for cryptographic operations within the system. These tests focus on signing, verifying, encrypting, and decrypting data using RSA and ECC keys. The goal is to ensure the integrity and reliability of these operations, which are critical for the security of the system’s data and communications.

Overview

The purpose of this module is to thoroughly test cryptographic operations, specifically focusing on:

  • Signing and verifying data with RSA and ECC keys.
  • Encrypting and decrypting data using RSA keys.

Test Cases

Signing and Verifying Data

  1. test_sign_and_verify_rsa_1024
    • Description: Tests signing and verifying data using a 1024-bit RSA key.
    • Steps:
      1. Initialize YubiKeyProvider with key ID and configuration.
      2. Initialize the HSM module on the YubiKey device.
      3. Create a 1024-bit RSA key pair.
      4. Sign predefined data.
      5. Verify the signature of the signed data.
  2. test_sign_and_verify_rsa_2048
    • Description: Tests signing and verifying data using a 2048-bit RSA key.
    • Steps: Follow the same steps as test_sign_and_verify_rsa_1024, but with a 2048-bit key configuration.
  3. test_sign_and_verify_ecc_256
    • Description: Tests signing and verifying data using a 256-bit ECC key.
    • Steps: Follow the same steps as test_sign_and_verify_rsa_1024, but with a 256-bit ECC key configuration.
  4. test_sign_and_verify_ecc_384
    • Description: Tests signing and verifying data using a 384-bit ECC key.
    • Steps: Follow the same steps as test_sign_and_verify_rsa_1024, but with a 384-bit ECC key configuration.

Encrypting and Decrypting Data

  1. test_encrypt_and_decrypt_rsa_1024
    • Description: Tests encrypting and decrypting data using a 1024-bit RSA key.
    • Steps:
      1. Initialize YubiKeyProvider with key ID and configuration.
      2. Initialize the HSM module on the YubiKey device.
      3. Create a 1024-bit RSA key pair.
      4. Encrypt predefined data.
      5. Decrypt the encrypted data and verify it matches the original data.
  2. test_encrypt_and_decrypt_rsa_2048
    • Description: Tests encrypting and decrypting data using a 2048-bit RSA key.
    • Steps: Follow the same steps as test_encrypt_and_decrypt_rsa_1024, but with a 2048-bit key configuration.

Test Procedures

Each test case follows these general steps:

  1. Initialization: Set up the YubiKeyProvider with necessary parameters.
  2. Module Initialization: Initialize the HSM module on the YubiKey device.
  3. Key Creation: Generate a key pair according to the test requirements.
  4. Operation: Perform the cryptographic operation (sign, verify, encrypt, decrypt).
  5. Verification: Ensure the operation’s outcome matches the expected result.

Test Parameters

  • RSA Keys: Tests cover 1024-bit and 2048-bit key sizes.
  • ECC Keys: Tests cover 256-bit and 384-bit key sizes.

Test Assumptions

  • A YubiKey device is connected and configured correctly.
  • The device is accessible via the system’s USB interface.

Expected Behavior

  • Successful key creation, signing, verification, encryption, and decryption without errors.
  • Failures in these operations are considered test failures and should be reported.

Dependencies

```rust use super::YubiKeyProvider; use crate::common::{ crypto::algorithms::{ encryption::{AsymmetricEncryption, EccCurves, EccSchemeAlgorithm}, KeyBits, }, error::SecurityModuleError, traits::module_provider::Provider, }; use crate::hsm::{core::error::HsmError, HsmProviderConfig}; use ::yubikey::{ piv::{self, AlgorithmId, RetiredSlotId, SlotId}, Error, YubiKey, }; use base64::{engine::general_purpose, Engine}; use std::any::Any; use std::sync::{Arc, Mutex}; use tracing::instrument; use x509_cert::der::En ; use yubikey::MgmKey; Constants SLOTS rust

const SLOTS: [RetiredSlotId; 20] = [ RetiredSlotId::R1, RetiredSlotId::R2, // … remaining slots RetiredSlotId::R20, ]; SLOTSU32 rust

const SLOTSU32: [u32; 20] = [ 0x005f_c10d, // … remaining slots 0x005f_c120, ];

Provider Implementation create_key Creates a new cryptographic key identified by the provider-given key_id.#Example Below is an example of how to use the YubiKeyProvider to sign data. use super::YubiKeyProvider; use crate::{ common::{ crypto::algorithms::{ encryption::{AsymmetricEncryption, EccCurves, EccSchemeAlgorithm}, KeyBits, }, error::SecurityModuleError, traits::key_handle::KeyHandle, }, hsm::core::error::HsmError, }; use yubikey::{piv, AlgorithmId, SlotId, MgmKey}; use base64::{engine::general_purpose, Engine}; use openssl::{ec::EcKey, hash::MessageDigest, pkey::PKey, rsa::{Padding, Rsa}, sign::Verifier}; use rsa::sha2::Digest; use sha2::Sha256; use tracing::instrument; use x509_cert::der::zeroize::Zeroizing;

const BYTES_1024: usize = 128; const BYTES_2048: usize = 256;

/// Provides cryptographic operations for asymmetric keys on a YubiKey. pub struct YubiKeyProvider { yubikey: Option<Mutex>, pin: Option, management_key: Option<Vec>, key_algo: Option, slot_id: Option, pkey: String, }

impl KeyHandle for YubiKeyProvider { /// Signs data using the cryptographic key on a YubiKey. #[instrument] fn sign_data(&self, data: &[u8]) -> Result<Vec, SecurityModuleError> { let yubikey = self.yubikey.as_ref().unwrap(); let mut yubikey = yubikey.lock().unwrap(); let data = data.to_vec(); let key_algo = self.key_algo.unwrap();

    // Input gets hashed with SHA-256
    let mut hasher = Sha256::new();
    hasher.update(data);
    let data = hasher.finalize();
    let mut data: &[u8] = &data;

    // TODO: After PIN input implementation in App, insert code for re-authentication
    let verify = yubikey.verify_pin(self.pin.as_ref());
    if !verify.is_ok() {
        return Err(SecurityModuleError::Hsm(HsmError::DeviceSpecific(
            "PIN verification failed".to_string(),
        )));
    }
    let auth = yubikey.authenticate(MgmKey::new(self.management_key.unwrap()).unwrap());
    if !auth.is_ok() {
        return Err(SecurityModuleError::Hsm(HsmError::DeviceSpecific(
            "Authentication  failed".to_string(),
        )));
    }

    let signature: Result<Zeroizing<Vec<u8>>, yubikey::Error>;
    let mut vec_data: Vec<u8> = create_digest_info(data).unwrap();
    let algorithm_id: AlgorithmId;

    match key_algo {
        AsymmetricEncryption::Rsa(KeyBits::Bits1024) => {
            algorithm_id = AlgorithmId::Rsa1024;
            vec_data = apply_pkcs1v15_padding(&vec_data, BYTES_1024);
            data = &vec_data.as_slice();
        }
        AsymmetricEncryption::Rsa(KeyBits::Bits2048) => {
            algorithm_id = AlgorithmId::Rsa2048;
            vec_data = apply_pkcs1v15_padding(&vec_data, BYTES_2048);
            data = vec_data.as_slice();
        }

        AsymmetricEncryption::Ecc(EccSchemeAlgorithm::EcDsa(EccCurves::P256)) => {
            algorithm_id = AlgorithmId::EccP256;
        }
        AsymmetricEncryption::Ecc(EccSchemeAlgorithm::EcDsa(EccCurves::P384)) => {
            algorithm_id = AlgorithmId::EccP384;
        }
        _ => {
            return Err(SecurityModuleError::Hsm(HsmError::DeviceSpecific(
                "Key Algorithm not supported".to_string(),
            )));
        }
    }
    signature = piv::sign_data(
        &mut yubikey,
        data,
        algorithm_id,
        SlotId::Retired(self.slot_id.unwrap()),
    );
    match signature {
        Ok(buffer) => {
            let signature = general_purpose::STANDARD.encode(&buffer);
            let signature = general_purpose::STANDARD
                .decode(signature)
                .expect("Failed to decode signature");
            Ok(signature)
        }
        Err(err) => Err(SecurityModuleError::Hsm(HsmError::DeviceSpecific(
            err.to_string(),
        ))),
    }
} }

Arguments key_id: A string slice that uniquely identifies the key. config: A boxed ProviderConfig containing configuration details for key generation. Returns A Result that, on success, contains Ok(()). On failure, it returns a SecurityModuleError.

Example rust

#[instrument] fn create_key( &mut self, key_id: &str, config: Box, ) -> Result<(), SecurityModuleError> { // Implementation here } load_key Loads an existing cryptographic key identified by key_id.

Arguments key_id: A string slice that uniquely identifies the key. config: A boxed ProviderConfig containing configuration details. Returns A Result that, on success, contains Ok(()). On failure, it returns a SecurityModuleError.

Example rust

#[instrument] fn load_key(&mut self, key_id: &str, config: Box) -> Result<(), SecurityModuleError> { // Implementation here } initialize_module Initializes the YubiKey module and returns a handle for cryptographic operations.

Arguments key_algorithm: The asymmetric encryption algorithm to be used for the key. Returns A Result that, on success, contains Ok(()). On failure, it returns a Yubikey based Error.

Example rust

#[instrument] fn initialize_module(&mut self) -> Result<(), SecurityModuleError> { // Implementation here } Helper Functions save_key_object Saves the key object to the YubiKey device.

Arguments yubikey: Reference to the YubiKey device. key_id: A string slice that uniquely identifies the key. slot_id: An address where an object will be stored. pkey: The public key which is intended to be stored. algo: Algorithm identifier. Returns A Result that, on success, contains Ok(()). On failure, it returns a yubikey::Error.

Example rust

fn save_key_object( yubikey: &mut YubiKey, key_id: &str, slot_id: u32, pkey: &str, algo: &str, ) -> Result<(), yubikey::Error> { // Implementation here } parse_slot_data Parses the data from a YubiKey slot.

Arguments data: Reference to the data array. Returns A Result that, on success, contains Ok((key_name, slot, public_key, algo)). On failure, it returns a SecurityModuleError.

Example rust

fn parse_slot_data(data: &[u8]) -> Result<(String, String, String, String), SecurityModuleError> { // Implementation here } get_free_slot Gets a free slot for storing a key object.

Arguments yubikey: Reference to the YubiKey device. Returns A Result that, on success, contains Ok(RetiredSlotId). On failure, it returns a SecurityModuleError.

Example rust

fn get_free_slot(yubikey: &mut YubiKey) -> Result<RetiredSlotId, SecurityModuleError> { // Implementation here } get_reference_u32slot Converts a RetiredSlotId to its corresponding u32 value.

Arguments slot: The RetiredSlotId to be converted. Returns The corresponding u32 value of the RetiredSlotId.

Example rust

fn get_reference_u32slot(slot: RetiredSlotId) -> u32 { // Implementation here } list_all_slots Lists all slots with their corresponding key information.

Arguments yubikey: Reference to the YubiKey device. Returns A Result that, on success, contains Ok(Vec) with information about all slots. On failure, it returns a SecurityModuleError.

Example rust

fn list_all_slots(yubikey: &mut YubiKey) -> Result<Vec, SecurityModuleError> { // Implementation here } License This project is licensed under the MIT License - see the LICENSE file for details.

YubiKey Provider Documentation

Dependencies

```rust use super::YubiKeyProvider; use crate::common::{ crypto::algorithms::{ encryption::{AsymmetricEncryption, EccCurves, EccSchemeAlgorithm}, KeyBits, }, error::SecurityModuleError, traits::module_provider::Provider, }; use crate::hsm::{core::error::HsmError, HsmProviderConfig}; use ::yubikey::{ piv::{self, AlgorithmId, RetiredSlotId, SlotId}, Error, YubiKey, }; use base64::{engine::general_purpose, Engine}; use std::any::Any; use std::sync::{Arc, Mutex}; use tracing::instrument; use x509_cert::der::En ; use yubikey::MgmKey; Constants SLOTS rust

const SLOTS: [RetiredSlotId; 20] = [

RetiredSlotId::R1,
RetiredSlotId::R2,
RetiredSlotId::R3,
RetiredSlotId::R4,
RetiredSlotId::R5,
RetiredSlotId::R6,
RetiredSlotId::R7,
RetiredSlotId::R8,
RetiredSlotId::R9,
RetiredSlotId::R10,
RetiredSlotId::R11,
RetiredSlotId::R12,
RetiredSlotId::R13,
RetiredSlotId::R14,
RetiredSlotId::R15,
RetiredSlotId::R16,
RetiredSlotId::R17,
RetiredSlotId::R18,
RetiredSlotId::R19,
RetiredSlotId::R20, ];

SLOTSU32

rust

const SLOTSU32: [u32; 20] = [ 0x005f_c10d, 0x005f_c10e, 0x005f_c10f, 0x005f_c110, 0x005f_c111, 0x005f_c112, 0x005f_c113, 0x005f_c114, 0x005f_c115, 0x005f_c116, 0x005f_c117, 0x005f_c118, 0x005f_c119, 0x005f_c11a, 0x005f_c11b, 0x005f_c11c, 0x005f_c11d, 0x005f_c11e, 0x005f_c11f, 0x005f_c120, ];

Provider Implementation

create_key Creates a new cryptographic key identified by the provider-given key_id.

Arguments key_id: A string slice that uniquely identifies the key. config: A boxed ProviderConfig containing configuration details for key generation. Returns A Result that, on success, contains Ok(()). On failure, it returns a SecurityModuleError.

Example rust

[instrument]

fn create_key( &mut self, key_id: &str, config: Box, ) -> Result<(), SecurityModuleError> { // Implementation here }

load_key

Loads an existing cryptographic key identified by key_id.

Arguments key_id: A string slice that uniquely identifies the key. config: A boxed ProviderConfig containing configuration details. Returns A Result that, on success, contains Ok(()). On failure, it returns a SecurityModuleError.

Example rust

#[instrument] fn load_key(&mut self, key_id: &str, config: Box) -> Result<(), SecurityModuleError> { // Implementation here }

initialize_module

Initializes the YubiKey module and returns a handle for cryptographic operations.

Arguments key_algorithm: The asymmetric encryption algorithm to be used for the key. Returns A Result that, on success, contains Ok(()). On failure, it returns a Yubikey based Error.

Example rust

#[instrument] fn initialize_module(&mut self) -> Result<(), SecurityModuleError> { // Implementation here } Helper Functions save_key_object Saves the key object to the YubiKey device.

Arguments

yubikey: Reference to the YubiKey device. key_id: A string slice that uniquely identifies the key. slot_id: An address where an object will be stored. pkey: The public key which is intended to be stored. algo: Algorithm identifier. Returns A Result that, on success, contains Ok(()). On failure, it returns a yubikey::Error.

Example rust

fn save_key_object( yubikey: &mut YubiKey, key_id: &str, slot_id: u32, pkey: &str, algo: &str, ) -> Result<(), yubikey::Error> { // Implementation here } parse_slot_data Parses the data from a YubiKey slot.

Arguments data: Reference to the data array. Returns A Result that, on success, contains Ok((key_name, slot, public_key, algo)). On failure, it returns a SecurityModuleError.

Example rust

fn parse_slot_data(data: &[u8]) -> Result<(String, String, String, String), SecurityModuleError> { // Implementation here } get_free_slot Gets a free slot for storing a key object.

Arguments yubikey: Reference to the YubiKey device. Returns A Result that, on success, contains Ok(RetiredSlotId). On failure, it returns a SecurityModuleError.

Example rust

fn get_free_slot(yubikey: &mut YubiKey) -> Result<RetiredSlotId, SecurityModuleError> { // Implementation here } get_reference_u32slot Converts a RetiredSlotId to its corresponding u32 value.

Arguments slot: The RetiredSlotId to be converted. Returns The corresponding u32 value of the RetiredSlotId.

Example rust

fn get_reference_u32slot(slot: RetiredSlotId) -> u32 { // Implementation here } list_all_slots Lists all slots with their corresponding key information.

Arguments yubikey: Reference to the YubiKey device. Returns A Result that, on success, contains Ok(Vec) with information about all slots. On failure, it returns a SecurityModuleError.

Example rust

fn list_all_slots(yubikey: &mut YubiKey) -> Result<Vec, SecurityModuleError> { // Implementation here }

Key Storage Security:

HSM (Hardware Security Module): Keys are stored within the cryptographic boundary of the HSM and are only used for cryptographic operations. Applications like OpenPGP on a YubiKey do not have direct access to private keys; they can only request the cryptographic processor to perform an operation using one of the protected keys (e.g., “please sign this hash using the private key with key handle N”). In summary, both TLS and OpenPGP can be used to implement different layers of security, with TLS securing the connection and OpenPGP protecting the data itself.

results matching ""

    No results matching ""