Adaptive AUTOSAR——Cryptography (VRTE3.0 R21-11)

2023-05-16

Cryptography模块是用于自适应汽车软件架构的密码学模块,主要用于实现各种安全功能,包括加密、解密、签名和验证等操作。它的主要作用包括:

  1. 安全通信:使用各种算法对数据进行加密和解密,确保在自适应汽车软件架构中进行安全通信。
  2. 数据完整性保护:使用各种算法对数据进行签名和验证,以防止数据被篡改或伪造
  3. 访问控制:提供各种访问控制机制,确保只有受信任的实体才能访问特定资源
  4. 安全更新:提供各种安全更新工具,确保在实时操作系统上安全地更新安全相关的软件组件。
  5. 密钥管理:提供各种密钥管理工具,包括密钥生成、存储、分配和撤销等,以确保密钥的安全性和可靠性。

总之,Adaptive AUTOSAR Cryptography模块是一个非常重要的模块,为自适应汽车软件架构中的安全功能提供了强大的支持,从而提高了汽车软件的安全性和可靠性。

此外,Adaptive AUTOSAR Cryptography模块还可以提供以下额外的功能:

安全日志记录:记录重要的安全事件和操作,以便进行后续审计和调查。

安全策略执行:实施各种安全策略,包括访问控制、数据完整性保护、身份认证等,确保系统遵循最佳的安全实践。

加密算法适配:支持各种加密算法和标准,如AES、RSA、TLS等,并提供相应的适配器,以便在不同的平台和环境下使用。

随机数生成:提供各种高质量的随机数生成器,以确保生成的随机数具有良好的随机性和安全性。

证书管理:支持数字证书的生成、存储和验证,以确保通信双方的身份认证和数据完整性保护。

安全芯片集成:提供与硬件安全模块(HSM)的集成支持,以实现更高级别的安全性和保护。

总之,Adaptive AUTOSAR Cryptography模块是自适应汽车软件架构中非常重要的一部分,它提供了各种密码学算法和工具,以保证汽车系统的安全性和可靠性,帮助汽车软件开发人员实现各种安全功能,从而确保汽车系统的安全性。

11.1 What is Cryptography?

Cryptography是自适应平台体系结构中的一个功能集群,负责为自适应应用程序提供加密功能

作为一个功能集群,Cryptography提供了允许以可移植和灵活的方式访问加密原语(即算法)的基础设施。

此外,由于有一层抽象,自适应平台的集成商可以利用加密原语的多个实现,而不需要在自适应应用程序内部进行任何代码更改。

11.1.1 Architecture

Cryptography的高层体系结构如图11.1所示。

功能分为三个领域:

  1. 密钥存储
  2. 提供加密算法程序管理
  3. 证书管理。

每个区域在功能上是分开的,相互作用。自适应平台API为它们之间的交互提供了便利。

11.1.1.1 密钥存储Key Storage

密钥存储负责密钥管理,包括密钥的安全存储(例如加密密钥),因此得名。

钥匙存储在钥匙槽中,每个槽可以存储一把钥匙

在自适应应用程序可以使用密钥之前,它需要知道它存储在哪个密钥槽中。这是通过InstanceSpecifier实现的,其工作原理如下:

Adaptive Application开发人员首先创建一个类型为CryptoKeySlotInterface的RPortPrototype,然后使用该端口原型的InstanceSpecifier来访问密钥槽。

因此,自适应应用程序从不直接引用特定的密钥槽,而是引用RPortPrototype

因此,积分器可以在映射期间自由选择任何键槽。密钥存储概述如图11.2所示。

出于安全原因,自适应应用程序无法访问原始密钥材料而是使用密钥句柄。这种设计确保了自适应应用程序使用的任何密钥在应用程序受损的情况下保持安全(换句话说,自适应应用程序不应该泄露密钥)。

11.1.1.2提供加密程序管理 Crypto Provider Management

提供加密程序负责实现加密原语,并使自适应应用程序能够以可移植的方式在提供程序之间切换。

加密提供程序的使用使自适应应用程序能够执行基本的加密操作(例如加密或解密)。

如图11.3所示:

开发人员首先创建一个CryptoProviderInterface类型的RPortPrototype

然后使用该端口的InstanceSpecifier来访问所实现的功能

在部署过程中,集成商将此端口映射到可用的加密提供程序。

从自适应应用程序的角度来看,加密提供商是可交换的(假设它们实现相同的功能),集成商有责任选择正确的实现;不期望每个可用的加密提供方(即加密库)将实现相同的一组算法。

此外,当需要时间敏感的计算时,可能需要硬件加速

因此,Adaptive Platform支持每个Adaptive应用程序使用多个加密提供方,即使不同提供方支持的实现可能有所不同。

11.1.1.3 X.509 Certificate Management

自适应平台支持国际电信联盟(ITU)的X.509标准[9]中所述的公钥证书管理

证书将有关密钥(它所认证的公钥)的信息有关该密钥所有者的信息绑定在一起

这允许证书的用户检查私钥所有者的身份,以及私钥是否与公钥匹配

证书管理负责证书存储和证书吊销列表(CRL)。

11.2 Configuration and Workflow

加密工作流程分为两个阶段:

  1. 应用程序设计(第12.1节)
  2. 集成(第11.2节)。

密钥和加密提供者的工作流程非常相似,主要区别在于元素和属性的名称和类型

11.2.1 Application Design

此版本的RTA-VRTE入门套件不支持加密的ARXML配置。不使用端口接口,自适应应用程序使用预定义的值(见第11.2.2.1节)。

然而,Adaptive AUTOSAR规范规定必须配置至少一个加密提供程序才能执行任何加密操作

这些要求已经反映在密码学的工作中,因此,创建这样的元素是强制性的。

需要在Machine元素下创建包含Crypto Provider对象的Crypto Module实例化,以满足Crypto Daemon。

要在编辑器中创建加密模块实例化,请右键单击Machine -->New Child --> Module Instantiation --> Crypto Module Instantiation.

Figure 11.5: Creation of Crypto Module Instantiation element

To create a Crypto Provider, right-click on the Crypto Module Instantiation  -->New Child --> Crypto Provider.

Figure 11.6: Creation of Crypto Provider element

这些元素只需要创建,而不需要配置。计划在未来版本中提供完整的配置支持。

注意:配置这些元素后,应用程序将运行,但用户可能仍然会收到一个错误,即未配置CryptoKeySlots。这是因为,如前所述,还没有添加对加密的ARXML配置的支持。但是,此错误不会影响应用程序的工作。

11.2.2 Integration

在使用之前,必须将每个功能集群集成并部署到机器上。集成确保每个功能集群都得到了正确配置,并且满足了任何运行时依赖关系。

11.2.2.1 Configuration

如上文第11.2.1节所述,RTA-VRTE入门套件V3.0中的加密配置选项是有限的,尤其是所有可用的密钥槽和加密提供程序都是硬编码的。作为固定配置的一部分,有五个通用键槽可用于自适应应用程序:

  • CryptoQTProcess/CryptoQTExecutable/RSCP_CryptoQTUser/customkeyslot1
  • CryptoQTProcess/CryptoQTExecutable/RSCP_CryptoQTUser/customkeyslot2
  • CryptoQTProcess/CryptoQTExecutable/RSCP_CryptoQTUser/customkeyslot3
  • CryptoQTProcess/CryptoQTExecutable/RSCP_CryptoQTUser/customkeyslot4
  • CryptoQTProcess/CryptoQTExecutable/RSCP_CryptoQTUser/customkeyslot5

在创建用于识别密钥槽的InstanceSpecifier对象时,自适应应用程序应使用上面的字符串之一,而不是第11.1.1.1节中所述的RPortPrototype的元模型标识符。

用于密钥存储的密钥槽文件由集成商准备,因此RTA-VRTE入门套件不会创建它们。

准备好的文件可以是空的——假设密钥注入发生在运行时,但一旦注入,它们就可以重新用于测试目的。集成商应在文件系统上创建以下文件

  • /opt/vrte/crypto_daemon/per/type2/customkeyslot1.bin
  • /opt/vrte/crypto_daemon/per/type2/customkeyslot2.bin
  • /opt/vrte/crypto_daemon/per/type2/customkeyslot3.bin
  • /opt/vrte/crypto_daemon/per/type2/customkeyslot4.bin
  • /opt/vrte/crypto_daemon/per/type2/customkeyslot5.bin

如果项目使用文件系统权限来保护文件不受未经授权的访问,则集成程序必须相应地配置加密。特别是,应该在执行编辑器中将正确的用户和组ID分配给代表加密的守护进程进程(有关更多详细信息,请参阅第4.5.3节)。

警告:未能为密钥存储创建文件将导致自定义密钥槽无法使用

例如,它们将无法从自适应应用程序访问。如果Cryptographic没有访问文件系统上现有相关文件的权限,也会发生同样的情况。

RTA-VRTE入门套件V3.0.0支持单个加密提供程序。创建InstanceSpecifier对象时,自适应应用程序应使用字符串wolfssl,而不是第11.1.1.2节中所述的RPortPrototype的元模型标识符。

11.2.2.2 Command-line Arguments

为crypto_demon可执行文件配置Process元素时,集成程序应创建一个值如下的命令行参数:

-k ecucfg

有关如何配置命令行参数的详细信息,请参阅第4.5.3节。

11.2.2.3 Cross Functional Cluster Dependencies

加密在运行时依赖于通信管理。为crypto_demon可执行文件配置Process元素时,集成程序应为Process arapipcd创建类型为RUNNING的Execution Dependency,以便加密库和加密服务守护程序可以相互通信。有关配置执行依赖项的详细信息,请参见第4.5.5节。

这些依赖关系的图形表示如图11.7所示。加密没有引入通信管理的额外配置要求,有关如何配置通信管理的详细信息,请参阅第9章。

11.2.2.4 External Dependencies

加密技术使用wolfSSL库作为加密提供程序。开源版本可以从下载https://github.com/wolfSSL/wolfssl.

RTA-VRTE入门套件V3.0.0已经通过库的4.3.0版本进行了测试。

11.2.3 Supported Algorithms

RTA-VRTE入门套件V3.0.0支持多种加密算法。使用密码学时,您需要知道要使用的算法的名称。创建加密上下文(执行加密计算的对象)时需要这样做,有关更多信息,请参阅第11.3.4节。

本节列出RTA-VRTE入门套件V3.0.0支持的算法名称。

Hash Functions : 哈希函数:

  • “SHA-1”
  • “SHA-224”
  • “SHA-256”
  • “SHA-384”
  • “SHA-512”

Message Authentication Codes : 消息身份验证代码:

  • “GMAC/AES-128”
  • “GMAC/AES-192”
  • “GMAC/AES-256”
  • “CMAC/AES-128”
  • “CMAC/AES-192”
  • “CMAC/AES-256”

Digital Signatures : 数字签名:

  • “RSASSA/PSS,SHA-256”
  • “RSASSA/PSS,SHA-256,RSA-3072”
  • “RSASSA/PSS,SHA-256,RSA-4096”
  • “RSASSA/PKCS1-v1_5,SHA-256”
  • “RSASSA/PKCS1-v1_5,SHA-256,RSA-3072”
  • “RSASSA/PKCS1-v1_5,SHA-256,RSA-4096”
  • “Ed25519”
  • “ECDSA/SECP256R1/SHA-256”

Block Ciphers : 分组密码:

  • “ECB/AES-128/PKCS7”
  • “ECB/AES-192/PKCS7”
  • “ECB/AES-256/PKCS7”
  • “CBC/AES-128/PKCS7”
  • “CBC/AES-192/PKCS7”
  • “CBC/AES-256/PKCS7”
  • “CTR/AES-128”
  • “CTR/AES-192”
  • “CTR/AES-256”
  • “GCM/AES-128”
  • “GCM/AES-192”
  • “GCM/AES-256”

Random Number Generators : 随机数生成器:

  • “RNG/GLOBAL”

Key Derivation Functions : 关键派生函数:

  • “PBKDF2,SHA-1”
  • “PBKDF2,SHA-256”
  • “PBKDF2,MD5”
  • “AES-MP”

注意:在对密钥注入的密钥进行编码的情况下,只有算法是相关的,而不是操作类型,请参见第11.3.3.1节中的密钥导入模式。

11.3 Working with Cryptography

软件开发人员。我们将首先关注:

  1. 加密软件包的安装
  2. 软件开发的编译阶段,
  3. 转到运行时方面

这里的重点将是密钥注入,然后是加密/解密。这一概述应该为密码学的进一步探索奠定坚实的基础。

11.3.1 Crypto Package Installation加密包安装

在开始开发使用加密的自适应应用程序之前,用户必须首先安装包含加密功能集群和wolfSSL库的加密包。

注意:Crypto软件包目前尚未作为RTA-VRTE入门套件的一部分发布,而是单独分发的。可以通过联系ETAS技术支持来请求该软件包,请参阅第24章。

要安装Crypto软件包,请将Crypto-SK_<ver_number>.tar文件放在RTA-VRTE入门套件内的桌面上,然后打开终端窗口并执行以下命令:

$cd /opt/etas/vrte/sdk
$tar -xvf ~/Desktop/Crypto-SK_<ver_number>.tar

第一个命令将当前文件夹更改为安装RTA-VRTE SDK的文件夹。第二个命令将提取并安装Crypto包。

11.3.2 Software Compilation

注意:本节中的示例假设使用基于CMake的构建系统,尽管所提供的信息应广泛适用并独立于构建系统。

编译自适应应用程序时,需要向编译器提供包含文件和链接库的位置。使用加密功能集群的自适应应用程序也将依赖于执行客户端和加密库——使用以下CMake包可以很容易地找到这些库:

find_package(exm-executionclient-lib CONFIG REQUIRED)

find_package(crypto REQUIRED)

上述命令将定位所需的包,并创建包含库和include目录信息的变量。以下命令将此信息应用于特定可执行文件的生成过程:

target_include_directories(executable_name
${EXM_EXECUTIONCLIENT_LIB_INCLUDE_DIRS}
${CRYPTO_INCLUDE_DIRS} ...)

target_link_libraries(executable_name
${EXM_EXECUTIONCLIENT_LIB_LIBRARIES}
${CRYPTO_LIBRARIES} ...)

11.3.3 Key Injection密钥注入

使用钥匙槽内的钥匙之前,首先需要将其注入(即写入或保存)到钥匙存储器(或者更准确地说,注入到钥匙槽)。RTA-VRTE入门套件V3.0.0支持使用ImportPublicObject接口将加密密钥材料注入密钥存储槽。

AUTOSAR还支持易失性容器形式的临时密钥,这些临时密钥可以通过AllocVolatileContainer接口进行分配。临时密钥存储在RAM中,其寿命仅限于自适应应用程序的寿命,例如,它们不能存储在密钥槽中。临时密钥注入也由ImportPublicObject接口执行。

11.3.3.1 Key Import Schema 密钥导入架构

RTA-VRTE入门套件可以导入(即注入)根据提供的ASN.1架构(RTA\verte_key_import_schema.ASN)编码的密钥。导入架构定义如下:

在架构中指定的ImportFormat类型内部。必须定义以下值:

metadataVersionNumber:一个整数,表示当前数据(即对象内部的数据)编码所依据的架构版本。

对于RTA-VRTE入门套件V3.0.0,元数据版本号应设置为0(零)。

mObjectUidQwordMs、mObjectUidQwordLs和mObjectUidVersionStamp:它们一起形成加密对象唯一标识符(COUID)。

在AUTOSAR中,COUID分为两部分:

1、生成器Uid,由mObjectUidQwordMs.mObjectUidQ wordLs形成

2、唯一标识生成器生成(注入)的对象(密钥)的mObjectUid版本戳。

AUTOSAR要求每个密钥都有自己的COUID,对于注入的密钥,应在执行ASN.1编码时提供。在测试或早期开发阶段,建议使用简单的编号方案,例如0.1.1、0.1.2、1.3,但生产案例应使用中央密钥管理方案,该方案应提供适当的值。

请注意,在AUTOSAR中,存在一个空的COUID(Nil),它等于0.0.0,因此建议从0.1.1开始编号

当注入非对称密钥时,预计公钥和私钥将共享相同的COUID,但它们将因mObjectType而不同。

mObjectSize:mObject的大小(以字节为单位),当注入2048位密钥(例如RSA 2048密钥)时,mObjectSize应设置为256。

mObjectType:正在注入的键的类型。可用类型包括:

  1. kSymmetricKey
  2. kPrivateKey
  3. kPublicKey
  4. kSignature
  5. kSecretSeed

mAlgId:为其注入密钥的加密算法的ID。支持的加密算法ID包括:

  1. aes-128
  2. aes-192
  3. aes-256
  4. rsa-2048
  5. rsa-3072
  6. rsa-4096
  7. ed25519
  8. secp256R1
  9. curve25519、

mContentAllowedUsage:一个位字段,用于指定密钥的可用/支持的加密操作

可以使用以下位值(可以通过执行逐位OR运算符来组合多个值):

  1. kAllowPrototypedOnly = 0x0000
  2. kAllowDataEncryption = 0x0001
  3. kAllowDataDecryption = 0x0002
  4. kAllowSignature = 0x0004
  5. kAllowVerification = 0x0008
  6. kAllowKeyAgreement = 0x0010
  7. kAllowKeyDiversify = 0x0020
  8. kAllowRngInit = 0x0040
  9. kAllowKdfMaterial = 0x0080
  10. kAllowKeyExporting = 0x0100
  11. kAllowKeyImporting = 0x0200
  12. kAllowExactModeOnly = 0x8000
  13. kAllowDerivedDataEncryption = kAllowDataEncryption «16
  14. kAllowDerivedDataDecryption = kAllowDataDecryption «16
  15. kAllowDerivedSignature = kAllowSignature « 16
  16. kAllowDerivedVerification = kAllowVerification « 16
  17. kAllowDerivedKeyDiversify = kAllowKeyDiversify « 16
  18. kAllowDerivedRngInit = kAllowRngInit « 16
  19. kAllowDerivedKdfMaterial = kAllowKdfMaterial « 16
  20. kAllowDerivedKeyExporting = kAllowKeyExporting « 16
  21. kAllowDerivedKeyImporting = kAllowKeyImporting « 16
  22. kAllowDerivedExactModeOnly = kAllowExactModeOnly « 16

注:“«”运算符象征着左位移位。

mContentAllowedUsage设置为kAllowPrototypedOnly的密钥不能用于任何加密操作。只有在为以后的密钥注入保留密钥槽时,此值才有用。

mObjectEncoding:指定用于mObject的编码。mObjectEncoding的定义值为:

  •  raw
  •  der
  •  pem

RTA-VRTE入门套件支持密钥注入的原始格式,不应使用其他值。

mSessionFlag-指定这是否是一个临时(即会话)密钥。如果设置为true,即这是一个会话密钥,Adaptive Application将无法将此密钥存储在密钥槽中。

RTA-VRTE入门套件中未使用此标志。

mObject:按mObjectEncoding指定的方式编码的键的值

11.3.3.2 Key Encoding

在注入密钥之前,必须先对其进行编码

RTA-VRTE入门套件密钥导入模式如第11.3.3.1节所述,可在RTA\verte_key_import_schema.asn文件中找到。

ASN.1标准得到广泛支持,Adaptive Application开发人员可以使用任何合适的现成工具进行密钥编码——在本节中,将使用Python库asn1tools[3]。虽然代码示例是用Python编写的,但所提供的信息应该是广泛适用的,并且与语言无关。

在本节中,将使用NIST[12]的测试矢量。特别地,作为这种特定操作模式的AES算法的CBC模式对于要加密的短数据集和长数据集(又称纯文本)都能很好地工作。CBCMMT128.rsp文件中的测试向量COUNT_0将用作我们示例的基础:

COUNT = 0
KEY = 1f8e4973953f3fb0bd6b16662e9a3c17
IV = 2fe2b333ceda8f98f4a99b40d2cd34a8
PLAINTEXT = 45cf12964fc824ab76616ae2f4bf0822
CIPHERTEXT = 0f61c4d44c5147c03c195ad7e2cc12b2

第一步是导入asn1tools模块,并根据第11.3.3.1节中描述的模式创建一个字典来存储数据:

一旦描述了密钥,就可以将其编译为ASN.1模式。在编译过程中,对模式进行解析并检查其正确性——如果成功,则返回可用于编码的对象。

# Before we can encode a key, in accordance to ASN.1 schema,
# we first need to compile mentioned schema.
# Please note that we will use the DER format for encoding our key
# (this is specified by second parameter in the function call).
# Information about DER format can be found here:
# https://en.wikipedia.org/wiki/X.690#DER_encoding
rta_vrte_key_import = asn1tools.compile_files(
    ’rta_vrte_key_import_schema.asn’, ’der’
)

RTA-VRTE入门套件V3.0.0仅在导入密钥时支持DER格式。

关键材料编码(在ASN.1模式中设置)与容器编码(在对对象进行编码时设置)是分开的,因此这些值可能不同。

encode方法采用两个参数:

第一个参数是用于编码数据的模式中使用的类型的名称(rta_vrte_key_import_schema.asn只有一个类型——ImportFormat);

第二个参数是包含关键字及其描述的字典。

# Encode a key described by AES_count_0_key dictionary,
# using ImportFormat type from schema.
encoded = rta_vrte_key_import.encode(
’ImportFormat’, AES_count_0_key
)

成功编码将返回一个字节对象,该对象可以打印或写入文件。

# Print the encoded key to console.
print(’AES_count_0_key encoded:’)
print(encoded.hex().upper())
# And save it to a file.
print(’Writing AES_count_0_key to AES_count_0_key.hex file.’)
with open(’AES_count_0_key.hex’, ’wb’) as f:
f.write(encoded)

编码的密钥现在可以在运行时使用,并注入到密钥槽中。

11.3.3.3 Key Injection During Runtime

对密钥进行编码后(见第11.3.3.2节),可以将其注入到密钥槽中。

密钥注入代码可以分为五个不同的部分(注意,为了简洁起见,省略了ara::crypto和ara::core名称空间)。

  1. Load a key slot

加载一个密钥槽可以分为三个操作,第一个操作是创建一个InstanceSpecifier(识别我们想用于密钥注入的密钥槽),即将密钥存储在持久内存中的密钥槽。

RTA-VRTE入门套件包括预定义的键槽,请参见第11.2.2.1节。

auto instanceSpec = InstanceSpecifier("CryptoQTProcess/CryptoQTExecutable/RSCP_CryptoQTUser/customkeyslot1");

下一步是创建一个对象,用于访问机器上可用的密钥存储。请注意,LoadKeyStorageProvider

方法不采用任何参数,AUTOSAR规范——或者更准确地说是ara::crypto——假设只有一个(虚拟)密钥存储提供程序。

auto sp = LoadKeyStorageProvider();

最后一步是将选定的键槽加载到应用程序中。Load KeySlot方法返回一个密钥槽句柄,该句柄允许访问作为参数传递的InstanceSpecifier标识的密钥槽。

auto keySlot = sp->LoadKeySlot(instanceSpec).Value();

  1. Select the Crypto Provider

选择要用于密钥注入的加密提供程序与第一部分类似,因为它还创建了InstanceSpecifier

请注意,RTA-VRTE Starter Kit只支持一个加密提供程序,Adaptive Applications在创建实例说明符时应使用字符串wolfssl(请参阅第11.2.2.1节)。之后,可以使用LoadCryptoProvider方法加载加密提供程序并将InstanceSpecifier作为参数。

const InstanceSpecifier cryptoProv("wolfssl");

cryp::CryptoProvider::Uptr cp = LoadCryptoProvider(cryptoProv);

  1. Open the key slot

现在需要打开加载的键槽-如果不打开键槽,我们就无法使用它。当调用Open方法时,第二个参数控制是否在写访问模式下打开键槽。由于显而易见的原因,在注入密钥时,有必要对该密钥槽进行写访问,因此传递true,Open返回一个密钥句柄,允许直接对密钥执行操作。

// Open the key slot for injection

// (second parameter set to true -> write access)

auto ioi = keySlot->Open(false, true).Value();

  1. Prepare the crypto object

第四步的重点是准备一个要注入或导入到键槽中的对象。将编码密钥引入自适应应用程序时存在多个选项。例如,可以通过网络从密钥服务器检索编码的密钥,或者直接从机器上的文件中读取。

为了清楚起见,此示例对自适应应用程序的源代码中的编码密钥进行了硬编码。

// Encoded key stored as a vector of bytes
// COUNT_0 from CBCMMT128.rsp file
const std::vector<std::uint8_t> input {
0x30, 0x30, 0x81, 0x01, 0x00, 0x82, 0x01, 0x00,
0x83,
0x01, 0x01, 0x84, 0x01, 0x01, 0x85, 0x01, 0x10,
0x86,
0x01, 0x01, 0x87, 0x01, 0x01, 0x88, 0x01, 0x03,
0x89,
0x01, 0x00, 0x8a, 0x01, 0x00, 0x8b, 0x10, 0x1f,
0x8e,
0x49, 0x73, 0x95, 0x3f, 0x3f, 0xb0, 0xbd, 0x6b,
0x16,
0x66, 0x2e, 0x9a, 0x3c, 0x17
};

一旦编码的密钥可用于应用程序,就可以将其封装在ReadOnlyMemRegion中,并可以在下面的步骤中将其注入到密钥槽中。

ReadOnlyMemRegion inData{input.data(), input.size()};

  1. 密钥注入最后,密钥可以被注入到插槽中。使用ImportPublicObject方法执行注入,该方法将密钥句柄作为第一个参数,将编码密钥作为第二个参数,并将ara::crypto::CryptoObjectType::k未定义为第三个参数(对象的类型已在RTA-VRTE Starter Kit ASN.1导入模式中指定,请参阅第11.3.3.1节)。

auto importResult = cp->ImportPublicObject(*ioi,inData, CryptoObjectType::kUndefined);

在成功调用ImportPublicObject方法之后,密钥注入就完成了,可以使用该密钥。

11.3.4 Encryption and Decryption

本节将介绍一些执行加密和解密的示例代码(请注意,为了简洁起见,省略了ara::crypto和ara::core命名空间)。

11.3.4.1 Encryption

加密代码可以分为六个不同的部分:

1. Load a key slot

加载钥匙槽包括三个简单操作,如第11.3.3.3节所述。

InstanceSpecifier:标识存储密钥的密钥槽

LoadKeySlot:方法创建一个密钥槽句柄,该句柄提供对密钥的访问。

auto instanceSpec = InstanceSpecifier("CryptoQTProcess/
CryptoQTExecutable/RSCP_CryptoQTUser/customkeyslot1");
auto sp = LoadKeyStorageProvider();
auto keySlot = sp->LoadKeySlot(instanceSpec).Value();

2. Select the crypto provider

我们加载要用于执行加密的加密提供程序,该步骤在第11.3.3.3节中进行了描述。

const InstanceSpecifier cryptoProv("wolfssl");
cryp::CryptoProvider::Uptr cp =LoadCryptoProvider(cryptoProv);

3. Load the key

加载的钥匙槽现在需要使用Open方法打开(如果不打开钥匙槽,我们就无法访问存储在里面的钥匙)。打开密钥后,加密提供程序可以从该密钥槽加载密钥,以便直接访问该密钥,然后在加密操作期间使用该密钥。

auto resultIoi = keySlot->Open(false, false);
auto aesKey = cp->LoadSymmetricKey(*(resultIoi.Value()));

4.准备用于加密的对象

在本节中,我们准备用于加密的数据。我们正在使用NIST的测试矢量[12]

// Test vector COUNT_0 from CBCMMT128.rsp file
// Data is stored as a vector of bytes
const std::vector<std::uint8_t> initializationVector{
0x2f, 0xe2, 0xb3, 0x33, 0xce, 0xda, 0x8f, 0x98,
0xf4, 0xa9, 0x9b, 0x40, 0xd2, 0xcd, 0x34, 0xa8
};

const std::vector<std::uint8_t> plainText{
0x45, 0xcf, 0x12, 0x96, 0x4f, 0xc8, 0x24, 0xab,
0x76, 0x61, 0x6a, 0xe2, 0xf4, 0xbf, 0x08, 0x22
};

const std::vector<std::uint8_t> cipherText{
0x0f, 0x61, 0xc4, 0xd4, 0x4c, 0x51, 0x47, 0xc0,
0x3c, 0x19, 0x5a, 0xd7, 0xe2, 0xcc, 0x12, 0xb2
};

在我们可以将数据与ara::crypto API一起使用之前,我们需要将其封装在ReadOnlyMemRegion中。对于加密,我们需要包装初始化向量和纯文本(即未加密的数据)。

ReadOnlyMemRegion initializationVectorWrap{
    initializationVector.data(),
    initializationVector.size()
};

ReadOnlyMemRegion plainTextWrap{
    plainText.data(), plainText.size()
};

5.准备加密上下文

首先,为正在使用的加密算法找到供应商特定的ID。这是通过ConvertToAlgId方法完成的。作为输入,传递一个字符串,该字符串符合加密基元的AUTOSAR命名约定。RTA-VRTE入门套件V3.0.0支持的算法列表可在第11.2.3节中找到,“算法名称”列用作输入参数

在第二步中,创建一个加密上下文——一个将执行加密计算的对象。该算法是通过将其算法ID作为输入参数来指定的。最后,指定要执行的密钥和操作类型,在这种情况下是加密。

std::uint64_t algoID = cp->ConvertToAlgId("CBC/AES-128/PKCS7");
cryp::StreamCipherCtx::Uptr encryptionCtx = cp->CreateStreamCipherCtx(algoID).Value();
encryptionCtx->SetKey(*aesKey.Value(),CryptoTransform::kEncrypt);

6.执行加密

对于每个基于流密码的加密计算,调用Start和FinishBytes方法。该算法需要一个初始化向量initializationVectorWrap,因此它作为参数传递给Start方法。

FinishBytes方法接收未加密的数据作为输入,并向其添加填充。添加填充是为了将输入数据的大小增加到块大小的倍数(如果输入数据的尺寸已经是块大小的多倍,则添加整个填充块)。然后,在该示例中,它返回加密的数据。在这个调用之后,加密过程就结束了。

encryptionCtx->Start(initializationVectorWrap);
auto encryptedText = encryptionCtx->FinishBytes(plainTextWrap).Value();

在开发阶段,检查刚刚计算的加密文本(不包括填充)是否与预期值匹配可能很有用。

此步骤告诉加密(作为功能集群)是否正确部署。

为了增加置信度,使用公开可用的测试向量(例如本文件中使用的NIST[12]向量)。

11.3.4.2 Decryption

解密与加密非常相似,只是在几个关键位置有所不同。

加载密钥槽、选择加密提供程序和加载密钥的步骤是相同的(为了简洁,这里不再重复这些步骤的描述)。然而,有三个主要区别:

1.准备用于解密的对象

使用了来自NIST[12]的相同测试向量,因此除了预期的加密填充文本之外,数据保持不变。

// Data is stored as a vector of bytes

const std::vector<std::uint8_t> paddingText{
0x4c, 0x32, 0x37, 0xfc, 0x66, 0xa0, 0x7f, 0x6a,
0x7d, 0x2b, 0x26, 0x7b, 0xde, 0x1c, 0xf2, 0x90
};

接下来,组合密文和填充文本。Next, combine the cipher text and the padding text.

std::vector<std::uint8_t> paddedCipherText = cipherText;
paddedCipherText.insert(paddedCipherText.end(),paddingText.begin(), paddingText.end());

Then, wrap the encrypted data into a ReadOnlyMemRegion.

然后,将加密的数据包装到ReadOnlyMemRegion中。

ReadOnlyMemRegion initializationVectorWrap{
    initializationVector.data(),
    initializationVector.size()
};

ReadOnlyMemRegion cipherTextWrap{
    paddedCipherText.data(), paddedCipherText.size()
};

2.准备解密上下文

查找供应商特定算法ID的代码或创建加密上下文的代码没有更改。

当指定了正在使用的密钥时,在这种情况下解密还需要指定正在执行的操作类型:

std::uint64_t algoID = cp->ConvertToAlgId("CBC/AES-128/PKCS7");
cryp::StreamCipherCtx::Uptr decryptionCtx = cp->CreateStreamCipherCtx(algoID).Value();
decryptionCtx->SetKey(*aesKey.Value(),CryptoTransform::kDecrypt);

3.执行解密

对于解密,还需要调用StartFinishBytes方法。

Start的调用保持不变也将初始化向量传递到此处。

当我们调用FinishBytes方法时,加密的数据会作为参数传递。

decryptionCtx->Start(initializationVectorWrap);
auto decryptedText = decryptionCtx->FinishBytes(cipherTextWrap).Value();

可以看出,用于解密的代码与用于加密的代码非常相似。要检查加密功能集群是否已正确部署,请将计算值与测试向量中的数据进行交叉检查:

17.2.6 Cryptography

Cryptography安全管理功能集群中的加密由libcrypto_api.so库和守护进程crypto_demon表示。

功能集群依赖于通信管理功能集群和核心类型功能集群。

任何使用加密的自适应应用程序都必须链接到库libcrypto_api.so。 

Cryptography包括crypto_demon守护进程。crypto_demon进程依赖于WolfSSL®4.3作为其加密供应商。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Adaptive AUTOSAR——Cryptography (VRTE3.0 R21-11) 的相关文章

  • 比较 C# 和 ColdFusion 之间的密码哈希值 (CFMX_COMPAT)

    我有一个密码哈希值存储在一个表中 并通过以下 Coldfusion 脚本放置在那里 Hash Encrypt Form UserPassword GetSiteVars EnCode 我正在尝试在 C 应用程序中添加一些外部功能 我希望能够
  • PyCryptodome 错误:MAC 检查失败

    我正在 Python 3 中使用 Pycryptodome 开发一个加密程序 我试图加密一个 字节 字符串 然后解密它并验证 MAC 标签 当我验证它时 会抛出错误 这是代码 from Crypto Cipher import AES fr
  • 椭圆曲线上的点数

    如果您有以下形式的椭圆曲线 y 2 x 3 a x b mod p 有没有一个好的程序来计算这条曲线上的点数 我已经阅读过有关 Schoof 和 Schoof Elkies Atkin SEA 算法的信息 但我正在寻找开源实现 有谁知道一个
  • Android 指纹删除后密钥失效

    我正在 7 1 1 上的 Google Pixel 设备上进行测试 发现从设备中删除所有指纹后 我的私钥并未失效 我已经根据演示应用程序使用单个对称 SecretKey 进行了测试 并且按预期工作 但是使用非对称密钥对只会引发KeyPerm
  • 如何生成一定范围内的加密安全随机整数?

    我必须为生成密码的程序生成给定范围内的统一 安全的随机整数 现在我用这个 RNGCryptoServiceProvider rng new RNGCryptoServiceProvider byte rand new byte 4 rng
  • 应用程序的私有文件

    我想创建一个文件来存储一些只能由我的应用程序访问的数据 外部用户不应该能够访问该文件或对其进行任何更改 我将在文件中存储一个密钥 该密钥可能由我的应用程序访问需要时随时使用应用程序 使用Environment getDataDirector
  • java.lang.IllegalArgumentException:字符串 curve25519 不是 OID bouncycastle 1.52

    我正在尝试使用曲线 25519 的 java bouncy castle 1 52 实现生成密钥对 这给了我 java lang IllegalArgumentException 字符串 curve25519 不是 OID 这是我的代码 p
  • Java 中所有 UTF-8 字符的维吉尼亚密码

    我有一个简单的函数 用于通过 Java 中的 Vigen re 加密字符串 我省略了解密 因为这只是计算新值的行中的 而不是 但此功能仅适用于普通字母 A Z 如何更改该函数以使其支持小写字母以及大写字母和所有其他 UTF 8 字符 pub
  • 使用 .NET 加密 API 进行 RSA 盲签名?

    我想实施一个RSA 盲签名 http en wikipedia org wiki Blind signature Blind RSA signatures在 NET中 有什么办法可以使用标准System Security Cryptogra
  • 使用 node.js 解密 mcrypt 编码文本

    我使用 PHP 的 mcrypt 用 Blowfish 编码了文本 td mcrypt module open blowfish cfb iv mcrypt create iv mcrypt enc get iv size td MCRYP
  • 从 Java 访问 Firefox 的证书信任存储

    我对这个几乎失去希望了 我正在尝试使用 Firefox 安装附带的 NSS 库通过 PKCS 11 从 Java 7 访问 Firefox 信任存储 这是代码 import java security KeyStore import jav
  • 检查 canAuthenticateAgainstProtectionSpace 中的公钥

    我被要求根据已知值检查公钥canAuthenticateAgainstProtectionSpace 委托回调NSURLConnection http developer apple com library mac documentatio
  • RSA_public_decrypt 和 MS Crypto API 等效项

    我正在尝试开发许可证验证解决方案 许可证使用 OpenSSL 在服务器上进行编码RSA private encrypt功能 对于 Mac OS X 使用RSA public decrypt它就像一个魅力 在 Windows 上 我必须使用非
  • 验证 PDF 文档中的数字签名

    我正在尝试验证 PDF 数字签名 我知道 当 PDF 被签名时 会定义一个字节范围 嵌入证书 并且根据我的阅读 签名的消息摘要和时间戳也存储在 PDF 中 我已经可以提取证书并验证它们 现在我正在尝试验证 pdf 的完整性 但我的问题是我不
  • ECB、CBC、CFB哪种加密模式

    我的 php 脚本和 c 应用程序将相互传递一个 32 个字符长的哈希字符串 最佳模式是什么 我想到了 ECB 但我不确定 因为它说如果使用超过 1 个区块就不要使用 我如何知道该块有多大 他们偶尔会传递一个大文本文件 这将是加密此 CBC
  • 签署程序集“<程序集名称>.dll”时出现加密失败 –“提供程序版本错误”

    我从知名提供商处购买了身份验证证书 现在我想对程序集进行强命名 然后对其进行数字签名 这是我到目前为止所做的 通过运行 sn exe p keypair pfx key snk 从 pfx 中提取公钥 选中项目属性签名选项卡上的 对程序集进
  • 从 X509Certificate2 获取私钥时偶尔出现异常“指定的提供程序类型无效”或“密钥不存在”

    我在尝试从 X509Certificate2 证书获取私钥时遇到以下异常之一 System Security Cryptography CryptographicException 指定的提供程序类型无效 OR System Securit
  • 是否有用于 AES 的纯 Perl 模块?

    是否有用于 AES 的纯 Perl 模块 地穴 Rijndael PP http search cpan org dist Crypt Rijndael PP Rijndael 是底层算法AES https secure wikimedia
  • 在 C# 中生成 HMAC-SHA1

    我正在尝试使用 C 来使用 REST API API 创建者提供了以下用于 hmac 创建的伪代码 var key1 sha1 body var key2 key1 SECRET KEY var key3 sha1 key2 var sig
  • 这个巨大的正则表达式是如何工作的?

    我最近在我的一个目录中的一个名为的文件中找到了下面的代码doc php 文件功能或链接到文件管理器 做得非常好 基本上 它列出了当前目录中的所有文件 并且允许您更改目录 它可以访问我的所有文件 添加 重命名 信息 删除 我不记得安装过它 我

随机推荐

  • 深度学习基础——简单了解meta learning(来自李宏毅课程笔记)

    知乎同名账号同步发布 目录 一 初步了解二 和ML的差异三 应用了解 一 初步了解 我们以分类问题为例 xff0c 以前 xff0c 学习的目的是学习一个二元分类器 f f f xff1b 现在 xff0c 学习的
  • docker删除镜像及容器

    问题 清理服务器相关无用docker镜像及容器 删除镜像image 要删除 Docker 中的镜像 xff0c 可以使用 docker rmi 命令 请注意 xff0c 删除镜像前请确保不再需要它 xff0c 并且已经停止了使用该镜像的所有
  • 云技术:弹性计算ECS

    云计算 xff08 Cloud Computing xff09 被业界看作继大型计算机 个人计算机 互联网之后的第四次IT产业革命 xff0c 正日益成为未来互联网与移动技术相结合的一种新兴计算模式 云计算提供了IT基础设施和平台服务的新模
  • 如何在 docker 容器中安装 ROS

    本文记录在 docker ubuntu 18 04 环境下安装 ROS xff08 机器人操作系统 xff09 的过程 目录 文章目录 目录安装 ROS参考文献 安装 ROS 安装步骤如下 xff1a span class token co
  • DOCKER个人遇见小问题

    1 在写dockerfile的时候使用了echo的方式向文件里面写入 基本格式是 echo 34 想要写入的操作 34 gt gt gt 路径 dockerfile 1 因为是要向文件里面进行一个写操作同时希望建立容器的时候执行这个操作 所
  • Tips and Tricks for Visual Question Answering: Learnings from the 2017 Challenge阅读笔记

    本文提出了一种基于深度神经网络的VQA模型 xff0c 并报告了一套广泛的实验来确定每个设计选择的贡献和替代设计的性能 它提供了关于VQA模型各个组件重要性的指示器 xff0c 一 Summary of findings 1 使用一个sig
  • Ubuntu系统用VNCViewer连不上远程的解决办法

    有时Ubuntu重启电脑重新联网之后 xff0c 用VNCViewer远程时提示timeout 解决办法 点击Ubuntu电脑系统的设置按钮 xff0c 进入共享选项卡 检查远程登录是不是已经开启 xff0c 屏幕共享是不是活动状态 屏幕共
  • OAuth2.0的四种授权方式

    前言 OAuth 简单理解就是一种授权机制 xff0c 它是在客户端和资源所有者之间的授权层 xff0c 用来分离两种不同的角色 在资源所有者同意并向客户端颁发令牌后 xff0c 客户端携带令牌可以访问资源所有者的资源 OAuth2 0 是
  • PowerBuilder---合并相同单元格

    在用数据窗口显示数据时 xff0c 经常会出现某一列的连续多行内容是相同的 xff0c 在有中国特色的软件使用者看来这是一个很大的问题 一定要合并才能显得规范 如下图 xff1a PowerBuilder 合并相同单元格 qibin jin
  • 各行业的英语术语(绝对精华 1)

    不看不知道 各行业的英语术语 xff08 绝对精华 xff09 化妆品中英文对照 makeup xff08 粉底 xff09 mask xff08 面膜 xff09 mascara xff08 睫毛膏 xff09 milk xff08 乳
  • SD-WAN与SDN:揭开差异 如何选择虚拟化网络

    随着物联网 工业互联网等新兴业务场景的不断涌现 xff0c 网络正面临着开放 融合 智能化 个性化等需求 在SDN进入稳定爬升期 xff0c 还未完全落地之时 xff0c 以SD WAN xff08 软件定义的广域网 xff09 为代表的新
  • H5实例 移动端页面练习

    文章目录 标签知识点 标签知识点 name 61 viewport xff1b 屏幕设定maximum scale 61 1 0 minimum scale 61 1 0 initial scale 61 1 0 xff1b 最大最小缩放比
  • SSH修改远程端口后无法登录的解决办法

    参考 xff1a https www cnblogs com opswa p 16076001 html SSH是一种网络协议 xff0c 用于计算机之间的加密登录 如果一个用户从本地计算机 xff0c 使用SSH协议登录另一台远程计算机
  • 串口调试助手如何使用

    需要设置好对应的串口端口 xff0c 波特率 校验位 数据位 停止位 xff0c 然后打开串口 这是一个绿色版的 xff0c 比深蓝串口调试助手好用的多
  • 来来来!我告诉你 AUTOSAR架构深度解析从入门到放弃

    如何快速学习AUTOSAR 关于AUTOSAR的背景和架构信息 xff0c 这里就不详细展开了 大家可以参看 xff1a AUTOSAR的分层架构 一文了解 今天我们重点讲讲如何快速学习AUTOSAR架构的方法 如何获取规范文档 xff1f
  • 智能指针make_unique 与make_shared 的知识介绍

    关于make unique的构造及使用例程 xff0c MSDN的讲解非常详细 xff08 https msdn microsoft com zh cn library dn439780 aspx xff09 使用过程中 xff0c 主要有
  • Adaptive AutoSAR 标准介绍

    关于自适应AutoSAR 平台 自适应autosar 平台实现了adaptive applications的运营环境 它提供了两种接口 xff0c 一种是service 一种是API 平台功能分成两部分 xff1a service部分和ad
  • MPU和MCU的区别

    MCU指的是微控制 器 集合了FLASH RAM和一些外围器件 MCU一般使用片内FLASH来存储和执行程序代码 MPU指的是微处理 器 FLASH和RAM则需要设计者自行搭建 xff0c 当然MCU也可以外扩 MPU的电路设计相对MCU较
  • powerbuilder9 窗口高级配置

    一 无标题栏 办法 xff1a 把窗口类型配置成response或者popup xff0c 窗口属性中的titlebar属性就变成可以选择 xff0c 把titlebar属性的勾点掉 xff0c 就可以配置成无标题栏 xff0c main类
  • Adaptive AUTOSAR——Cryptography (VRTE3.0 R21-11)

    Cryptography模块是用于自适应汽车软件架构的密码学模块 xff0c 主要用于实现各种安全功能 xff0c 包括加密 解密 签名和验证 等操作 它的主要作用包括 xff1a 安全通信 xff1a 使用各种算法对数据进行加密和解密 x