关于 Android WrappedKeyEntry 要求的asn.1格式简析

WrappedKeyEntry 要求的ASN.1 der格式

借助 Android 9(API 级别 28)及更高版本,您能够利用 ASN.1 编码密钥格式将已加密密钥安全导入密钥库。Keymaster 随后会在密钥库中将密钥解密,因此密钥的内容永远不会以明文形式出现在设备的主机内存中。此过程提高了密钥解密的安全性。

注意:只有搭载 Keymaster 4 或更高版本的设备才支持该功能。
如需支持以安全方式将已加密密钥导入密钥库,请完成以下步骤:

生成目的为 PURPOSE_WRAP_KEY 的密钥对。建议也为该密钥对添加认证。

在您信任的服务器或机器上,生成 SecureKeyWrapper 应包含的 ASN.1 消息。

该封装容器包含以下架构:

KeyDescription ::= SEQUENCE {
        keyFormat INTEGER,
        authorizationList AuthorizationList
    }

    SecureKeyWrapper ::= SEQUENCE {
        wrapperFormatVersion INTEGER,
        encryptedTransportKey OCTET_STRING,
        initializationVector OCTET_STRING,
        keyDescription KeyDescription,
        secureKey OCTET_STRING,
        tag OCTET_STRING
    }

创建 WrappedKeyEntry 对象,传入字节数组形式的 ASN.1 消息。

将该 WrappedKeyEntry 对象传入接受 Keystore.Entry 对象的 setEntry() 的重载。

以上是密钥导入的步骤。
本文主要分析其中KeyDescription对于格式的要求,以供大家参考。

asn.1

这个格式参见百度。就是一种编码规范。简单理解就是type-length-value的模式。

KeyDescription

SEQUENCE 这个是asn.1的标示,是一个数据结构类型,有标准定义的,先不管他。

keyFormat INTEGER

这个keyFormat是一个枚举类型,不在上层Java,是在keymaster里面定义的。我目前找到的是keymaster 3.0里面的定义:

enum KeyFormat : uint32_t {
   X509 = 0,  /** for public key export */
   PKCS8 = 1, /** for asymmetric key pair import */
   RAW = 3,   /* for symmetric key import and export*/
};

这里可以看到,对称密钥是3,非对称密钥是2,0是x509的公钥证书格式。这里应该是标注后面使用的密钥的格式。

authorizationList AuthorizationList

这个类型有点复杂,官方文档有描述的:这里需要注意下,根据keymaster不同的版本,格式有点不一样,有三个版本。

AuthorizationList ::= SEQUENCE {
       purpose  [1] EXPLICIT SET OF INTEGER OPTIONAL,
       algorithm  [2] EXPLICIT INTEGER OPTIONAL,
       keySize  [3] EXPLICIT INTEGER OPTIONAL,
       digest  [5] EXPLICIT SET OF INTEGER OPTIONAL,
       padding  [6] EXPLICIT SET OF INTEGER OPTIONAL,
       ecCurve  [10] EXPLICIT INTEGER OPTIONAL,
       rsaPublicExponent  [200] EXPLICIT INTEGER OPTIONAL,
       rollbackResistance  [303] EXPLICIT NULL OPTIONAL,
       activeDateTime  [400] EXPLICIT INTEGER OPTIONAL,
       originationExpireDateTime  [401] EXPLICIT INTEGER OPTIONAL,
       usageExpireDateTime  [402] EXPLICIT INTEGER OPTIONAL,
       noAuthRequired  [503] EXPLICIT NULL OPTIONAL,
       userAuthType  [504] EXPLICIT INTEGER OPTIONAL,
       authTimeout  [505] EXPLICIT INTEGER OPTIONAL,
       allowWhileOnBody  [506] EXPLICIT NULL OPTIONAL,
       trustedUserPresenceRequired  [507] EXPLICIT NULL OPTIONAL,
       trustedConfirmationRequired  [508] EXPLICIT NULL OPTIONAL,
       unlockedDeviceRequired  [509] EXPLICIT NULL OPTIONAL,
       allApplications  [600] EXPLICIT NULL OPTIONAL,
       applicationId  [601] EXPLICIT OCTET_STRING OPTIONAL,
       creationDateTime  [701] EXPLICIT INTEGER OPTIONAL,
       origin  [702] EXPLICIT INTEGER OPTIONAL,
       rootOfTrust  [704] EXPLICIT RootOfTrust OPTIONAL,
       osVersion  [705] EXPLICIT INTEGER OPTIONAL,
       osPatchLevel  [706] EXPLICIT INTEGER OPTIONAL,
       attestationApplicationId  [709] EXPLICIT OCTET_STRING OPTIONAL,
       attestationIdBrand  [710] EXPLICIT OCTET_STRING OPTIONAL,
       attestationIdDevice  [711] EXPLICIT OCTET_STRING OPTIONAL,
       attestationIdProduct  [712] EXPLICIT OCTET_STRING OPTIONAL,
       attestationIdSerial  [713] EXPLICIT OCTET_STRING OPTIONAL,
       attestationIdImei  [714] EXPLICIT OCTET_STRING OPTIONAL,
       attestationIdMeid  [715] EXPLICIT OCTET_STRING OPTIONAL,
       attestationIdManufacturer  [716] EXPLICIT OCTET_STRING OPTIONAL,
       attestationIdModel  [717] EXPLICIT OCTET_STRING OPTIONAL,
       vendorPatchLevel  [718] EXPLICIT INTEGER OPTIONAL,
       bootPatchLevel  [719] EXPLICIT INTEGER OPTIONAL,
   }

具体参见文档:authorizationlist
里面的有一些枚举也是是在keymaster里面定义的,不是所有人都下载了源码,所以这里我直接贴出来。

/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.keymaster@3.0;

enum TagType : uint32_t {
    INVALID = 0 << 28, /* Invalid type, used to designate a tag as uninitialized */
    ENUM = 1 << 28,
    ENUM_REP = 2 << 28, /* Repeatable enumeration value. */
    UINT = 3 << 28,
    UINT_REP = 4 << 28, /* Repeatable integer value */
    ULONG = 5 << 28,
    DATE = 6 << 28,
    BOOL = 7 << 28,
    BIGNUM = 8 << 28,
    BYTES = 9 << 28,
    ULONG_REP = 10 << 28, /* Repeatable long value */
};

enum Tag : uint32_t {
    INVALID = TagType:INVALID | 0,

    /**
     * Tags that must be semantically enforced by hardware and software implementations.
     */

    /** Crypto parameters */
    PURPOSE = TagType:ENUM_REP | 1,    /** KeyPurpose. */
    ALGORITHM = TagType:ENUM | 2,      /** Algorithm. */
    KEY_SIZE = TagType:UINT | 3,       /** Key size in bits. */
    BLOCK_MODE = TagType:ENUM_REP | 4, /** BlockMode. */
    DIGEST = TagType:ENUM_REP | 5,     /** Digest. */
    PADDING = TagType:ENUM_REP | 6,    /** PaddingMode. */
    CALLER_NONCE = TagType:BOOL | 7,   /** Allow caller to specify nonce or IV. */
    MIN_MAC_LENGTH = TagType:UINT | 8, /* Minimum length of MAC or AEAD authentication tag in
                                        * bits. */
    KDF = TagType:ENUM_REP | 9,        /** KeyDerivationFunction. */
    EC_CURVE = TagType:ENUM | 10,      /** EcCurve. */

    /** Algorithm-specific. */
    RSA_PUBLIC_EXPONENT = TagType:ULONG | 200,
    ECIES_SINGLE_HASH_MODE = TagType:BOOL | 201, /* Whether the ephemeral public key is fed into the
                                                  * KDF. */
    INCLUDE_UNIQUE_ID = TagType:BOOL | 202,      /* If true, attestation certificates for this key
                                                  * will contain an application-scoped and
                                                  * time-bounded device-unique ID.*/

    /** Other hardware-enforced. */
    BLOB_USAGE_REQUIREMENTS = TagType:ENUM | 301, /** KeyBlobUsageRequirements. */
    BOOTLOADER_ONLY = TagType:BOOL | 302,         /** Usable only by bootloader. */

    /**
     * Tags that should be semantically enforced by hardware if possible and will otherwise be
     * enforced by software (keystore).
     */

    /** Key validity period */
    ACTIVE_DATETIME = TagType:DATE | 400,             /** Start of validity. */
    ORIGINATION_EXPIRE_DATETIME = TagType:DATE | 401, /* Date when new "messages" should no longer
                                                       * be created. */
    USAGE_EXPIRE_DATETIME = TagType:DATE | 402,       /* Date when existing "messages" should no
                                                       * longer be trusted. */
    MIN_SECONDS_BETWEEN_OPS = TagType:UINT | 403,     /* Minimum elapsed time between
                                                       * cryptographic operations with the key. */
    MAX_USES_PER_BOOT = TagType:UINT | 404,           /* Number of times the key can be used per
                                                       * boot. */

    /** User authentication */
    ALL_USERS = TagType:BOOL | 500,           /** Reserved for future use -- ignore. */
    USER_ID = TagType:UINT | 501,             /** Reserved for future use -- ignore. */
    USER_SECURE_ID = TagType:ULONG_REP | 502, /* Secure ID of authorized user or authenticator(s).
                                               * Disallowed if ALL_USERS or NO_AUTH_REQUIRED is
                                               * present. */
    NO_AUTH_REQUIRED = TagType:BOOL | 503,    /** If key is usable without authentication. */
    USER_AUTH_TYPE = TagType:ENUM | 504,      /* Bitmask of authenticator types allowed when
                                               * USER_SECURE_ID contains a secure user ID, rather
                                               * than a secure authenticator ID.  Defined in
                                               * HardwareAuthenticatorType. */
    AUTH_TIMEOUT = TagType:UINT | 505,        /* Required freshness of user authentication for
                                               * private/secret key operations, in seconds.  Public
                                               * key operations require no authentication.  If
                                               * absent, authentication is required for every use.
                                               * Authentication state is lost when the device is
                                               * powered off. */
    ALLOW_WHILE_ON_BODY = TagType:BOOL | 506, /* Allow key to be used after authentication timeout
                                               * if device is still on-body (requires secure on-body
                                               * sensor. */

    /** Application access control */
    ALL_APPLICATIONS = TagType:BOOL | 600, /* Specified to indicate key is usable by all
                                            * applications. */
    APPLICATION_ID = TagType:BYTES | 601,  /** Byte string identifying the authorized application. */
    EXPORTABLE = TagType:BOOL | 602,       /* If true, private/secret key can be exported, but only
                                            * if all access control requirements for use are
                                            * met. (keymaster2) */

    /**
     * Semantically unenforceable tags, either because they have no specific meaning or because
     * they're informational only.
     */
    APPLICATION_DATA = TagType:BYTES | 700,      /** Data provided by authorized application. */
    CREATION_DATETIME = TagType:DATE | 701,      /** Key creation time */
    ORIGIN = TagType:ENUM | 702,                 /** keymaster_key_origin_t. */
    ROLLBACK_RESISTANT = TagType:BOOL | 703,     /** Whether key is rollback-resistant. */
    ROOT_OF_TRUST = TagType:BYTES | 704,         /** Root of trust ID. */
    OS_VERSION = TagType:UINT | 705,             /** Version of system (keymaster2) */
    OS_PATCHLEVEL = TagType:UINT | 706,          /** Patch level of system (keymaster2) */
    UNIQUE_ID = TagType:BYTES | 707,             /** Used to provide unique ID in attestation */
    ATTESTATION_CHALLENGE = TagType:BYTES | 708, /** Used to provide challenge in attestation */
    ATTESTATION_APPLICATION_ID = TagType:BYTES | 709, /* Used to identify the set of possible
                                                       * applications of which one has initiated a
                                                       * key attestation */
    ATTESTATION_ID_BRAND = TagType:BYTES | 710,  /* Used to provide the device's brand name to be
                                                    included in attestation */
    ATTESTATION_ID_DEVICE = TagType:BYTES | 711, /* Used to provide the device's device name to be
                                                    included in attestation */
    ATTESTATION_ID_PRODUCT = TagType:BYTES | 712, /* Used to provide the device's product name to be
                                                     included in attestation */
    ATTESTATION_ID_SERIAL = TagType:BYTES | 713, /* Used to provide the device's serial number to be
                                                    included in attestation */
    ATTESTATION_ID_IMEI = TagType:BYTES | 714,   /* Used to provide the device's IMEI to be included
                                                    in attestation */
    ATTESTATION_ID_MEID = TagType:BYTES | 715,   /* Used to provide the device's MEID to be included
                                                    in attestation */
    ATTESTATION_ID_MANUFACTURER = TagType:BYTES | 716, /* Used to provide the device's manufacturer
                                                          name to be included in attestation */
    ATTESTATION_ID_MODEL = TagType:BYTES | 717,  /* Used to provide the device's model name to be
                                                    included in attestation */

    /** Tags used only to provide data to or receive data from operations */
    ASSOCIATED_DATA = TagType:BYTES | 1000, /** Used to provide associated data for AEAD modes. */
    NONCE = TagType:BYTES | 1001,           /** Nonce or Initialization Vector */
    AUTH_TOKEN = TagType:BYTES | 1002,      /* Authentication token that proves secure user
                                             * authentication has been performed.  Structure defined
                                             * in hw_auth_token_t in hw_auth_token.h. */
    MAC_LENGTH = TagType:UINT | 1003,       /** MAC or AEAD authentication tag length in bits. */

    RESET_SINCE_ID_ROTATION = TagType:BOOL | 1004, /* Whether the device has beeen factory reset
                                                    * since the last unique ID rotation.  Used for
                                                    * key attestation. */
};

enum Algorithm : uint32_t {
    /** Asymmetric algorithms. */
    RSA = 1,
    // DSA = 2, -- Removed, do not re-use value 2.
    EC = 3,

    /** Block ciphers algorithms */
    AES = 32,

    /** MAC algorithms */
    HMAC = 128,
};

/**
 * Symmetric block cipher modes provided by keymaster implementations.
 */
enum BlockMode : uint32_t {
    /**
     * Unauthenticated modes, usable only for encryption/decryption and not generally recommended
     * except for compatibility with existing other protocols. */
    ECB = 1,
    CBC = 2,
    CTR = 3,

    /**
     * Authenticated modes, usable for encryption/decryption and signing/verification.  Recommended
     * over unauthenticated modes for all purposes. */
    GCM = 32,
};

/**
 * Padding modes that may be applied to plaintext for encryption operations.  This list includes
 * padding modes for both symmetric and asymmetric algorithms.  Note that implementations should not
 * provide all possible combinations of algorithm and padding, only the
 * cryptographically-appropriate pairs.
 */
enum PaddingMode : uint32_t {
    NONE = 1, /** deprecated */
    RSA_OAEP = 2,
    RSA_PSS = 3,
    RSA_PKCS1_1_5_ENCRYPT = 4,
    RSA_PKCS1_1_5_SIGN = 5,
    PKCS7 = 64,
};

/**
 * Digests provided by keymaster implementations.
 */
enum Digest : uint32_t {
    NONE = 0,
    MD5 = 1, /* Optional, may not be implemented in hardware, will be handled in software if
              * needed. */
    SHA1 = 2,
    SHA_2_224 = 3,
    SHA_2_256 = 4,
    SHA_2_384 = 5,
    SHA_2_512 = 6,
};

/**
 * Supported EC curves, used in ECDSA
 */
enum EcCurve : uint32_t {
    P_224 = 0,
    P_256 = 1,
    P_384 = 2,
    P_521 = 3,
};

/**
 * The origin of a key (or pair), i.e. where it was generated.  Note that ORIGIN can be found in
 * either the hardware-enforced or software-enforced list for a key, indicating whether the key is
 * hardware or software-based.  Specifically, a key with GENERATED in the hardware-enforced list is
 * guaranteed never to have existed outide the secure hardware.
 */
enum KeyOrigin : uint32_t {
    GENERATED = 0, /** Generated in keymaster.  Should not exist outside the TEE. */
    DERIVED = 1,   /** Derived inside keymaster.  Likely exists off-device. */
    IMPORTED = 2,  /** Imported into keymaster.  Existed as cleartext in Android. */
    UNKNOWN = 3,   /* Keymaster did not record origin.  This value can only be seen on keys in a
                    * keymaster0 implementation.  The keymaster0 adapter uses this value to document
                    * the fact that it is unkown whether the key was generated inside or imported
                    * into keymaster. */
};

/**
 * Usability requirements of key blobs.  This defines what system functionality must be available
 * for the key to function.  For example, key "blobs" which are actually handles referencing
 * encrypted key material stored in the file system cannot be used until the file system is
 * available, and should have BLOB_REQUIRES_FILE_SYSTEM.  Other requirements entries will be added
 * as needed for implementations.
 */
enum KeyBlobUsageRequirements : uint32_t {
    STANDALONE = 0,
    REQUIRES_FILE_SYSTEM = 1,
};

/**
 * Possible purposes of a key (or pair).
 */
enum KeyPurpose : uint32_t {
    ENCRYPT = 0,    /* Usable with RSA, EC and AES keys. */
    DECRYPT = 1,    /* Usable with RSA, EC and AES keys. */
    SIGN = 2,       /* Usable with RSA, EC and HMAC keys. */
    VERIFY = 3,     /* Usable with RSA, EC and HMAC keys. */
    DERIVE_KEY = 4, /* Usable with EC keys. */
    WRAP_KEY = 5,   /* Usable with wrapping keys. */
};

/**
 * Keymaster error codes.
 */
enum ErrorCode : uint32_t {
    OK = 0,
    ROOT_OF_TRUST_ALREADY_SET = -1,
    UNSUPPORTED_PURPOSE = -2,
    INCOMPATIBLE_PURPOSE = -3,
    UNSUPPORTED_ALGORITHM = -4,
    INCOMPATIBLE_ALGORITHM = -5,
    UNSUPPORTED_KEY_SIZE = -6,
    UNSUPPORTED_BLOCK_MODE = -7,
    INCOMPATIBLE_BLOCK_MODE = -8,
    UNSUPPORTED_MAC_LENGTH = -9,
    UNSUPPORTED_PADDING_MODE = -10,
    INCOMPATIBLE_PADDING_MODE = -11,
    UNSUPPORTED_DIGEST = -12,
    INCOMPATIBLE_DIGEST = -13,
    INVALID_EXPIRATION_TIME = -14,
    INVALID_USER_ID = -15,
    INVALID_AUTHORIZATION_TIMEOUT = -16,
    UNSUPPORTED_KEY_FORMAT = -17,
    INCOMPATIBLE_KEY_FORMAT = -18,
    UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19,   /** For PKCS8 & PKCS12 */
    UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20, /** For PKCS8 & PKCS12 */
    INVALID_INPUT_LENGTH = -21,
    KEY_EXPORT_OPTIONS_INVALID = -22,
    DELEGATION_NOT_ALLOWED = -23,
    KEY_NOT_YET_VALID = -24,
    KEY_EXPIRED = -25,
    KEY_USER_NOT_AUTHENTICATED = -26,
    OUTPUT_PARAMETER_NULL = -27,
    INVALID_OPERATION_HANDLE = -28,
    INSUFFICIENT_BUFFER_SPACE = -29,
    VERIFICATION_FAILED = -30,
    TOO_MANY_OPERATIONS = -31,
    UNEXPECTED_NULL_POINTER = -32,
    INVALID_KEY_BLOB = -33,
    IMPORTED_KEY_NOT_ENCRYPTED = -34,
    IMPORTED_KEY_DECRYPTION_FAILED = -35,
    IMPORTED_KEY_NOT_SIGNED = -36,
    IMPORTED_KEY_VERIFICATION_FAILED = -37,
    INVALID_ARGUMENT = -38,
    UNSUPPORTED_TAG = -39,
    INVALID_TAG = -40,
    MEMORY_ALLOCATION_FAILED = -41,
    IMPORT_PARAMETER_MISMATCH = -44,
    SECURE_HW_ACCESS_DENIED = -45,
    OPERATION_CANCELLED = -46,
    CONCURRENT_ACCESS_CONFLICT = -47,
    SECURE_HW_BUSY = -48,
    SECURE_HW_COMMUNICATION_FAILED = -49,
    UNSUPPORTED_EC_FIELD = -50,
    MISSING_NONCE = -51,
    INVALID_NONCE = -52,
    MISSING_MAC_LENGTH = -53,
    KEY_RATE_LIMIT_EXCEEDED = -54,
    CALLER_NONCE_PROHIBITED = -55,
    KEY_MAX_OPS_EXCEEDED = -56,
    INVALID_MAC_LENGTH = -57,
    MISSING_MIN_MAC_LENGTH = -58,
    UNSUPPORTED_MIN_MAC_LENGTH = -59,
    UNSUPPORTED_KDF = -60,
    UNSUPPORTED_EC_CURVE = -61,
    KEY_REQUIRES_UPGRADE = -62,
    ATTESTATION_CHALLENGE_MISSING = -63,
    KEYMASTER_NOT_CONFIGURED = -64,
    ATTESTATION_APPLICATION_ID_MISSING = -65,
    CANNOT_ATTEST_IDS = -66,

    UNIMPLEMENTED = -100,
    VERSION_MISMATCH = -101,

    UNKNOWN_ERROR = -1000,
};

/**
 * Key derivation functions, mostly used in ECIES.
 */
enum KeyDerivationFunction : uint32_t {
    /** Do not apply a key derivation function; use the raw agreed key */
    NONE = 0,
    /** HKDF defined in RFC 5869 with SHA256 */
    RFC5869_SHA256 = 1,
    /** KDF1 defined in ISO 18033-2 with SHA1 */
    ISO18033_2_KDF1_SHA1 = 2,
    /** KDF1 defined in ISO 18033-2 with SHA256 */
    ISO18033_2_KDF1_SHA256 = 3,
    /** KDF2 defined in ISO 18033-2 with SHA1 */
    ISO18033_2_KDF2_SHA1 = 4,
    /** KDF2 defined in ISO 18033-2 with SHA256 */
    ISO18033_2_KDF2_SHA256 = 5,
};

/**
 * Hardware authentication type, used by HardwareAuthTokens to specify the mechanism used to
 * authentiate the user, and in KeyCharacteristics to specify the allowable mechanisms for
 * authenticating to activate a key.
 */
enum HardwareAuthenticatorType : uint32_t {
    NONE = 0,
    PASSWORD = 1 << 0,
    FINGERPRINT = 1 << 1,
    // Additional entries must be powers of 2.
    ANY = 0xFFFFFFFF,
};

struct KeyParameter {
    /**
     * Discriminates the uinon/blob field used.  The blob cannot be coincided with the union, but
     * only one of "f" and "blob" is ever used at a time. */
    Tag tag;
    union IntegerParams {
        /** Enum types */
        Algorithm algorithm;
        BlockMode blockMode;
        PaddingMode paddingMode;
        Digest digest;
        EcCurve ecCurve;
        KeyOrigin origin;
        KeyBlobUsageRequirements keyBlobUsageRequirements;
        KeyPurpose purpose;
        KeyDerivationFunction keyDerivationFunction;
        HardwareAuthenticatorType hardwareAuthenticatorType;

        /** Other types */
        bool boolValue;  // Always true, if a boolean tag is present.
        uint32_t integer;
        uint64_t longInteger;
        uint64_t dateTime;
    };
    IntegerParams f;  // Hidl does not support anonymous unions, so we have to name it.
    vec<uint8_t> blob;
};

struct KeyCharacteristics {
    vec<KeyParameter> softwareEnforced;
    vec<KeyParameter> teeEnforced;
};

/**
 * Data used to prove successful authentication.
 */
struct HardwareAuthToken {
    uint64_t challenge;
    uint64_t userId;             // Secure User ID, not Android user ID.
    uint64_t authenticatorId;    // Secure authenticator ID.
    uint32_t authenticatorType;  // HardwareAuthenticatorType, in network order.
    uint64_t timestamp;          // In network order.
    uint8_t[32] hmac;            // HMAC is computed over 0 || challenge || user_id ||
                                 // authenticator_id || authenticator_type || timestamp, with a
                                 // prefixed 0 byte (which was a version field in Keymaster1 and
                                 // Keymaster2) and the fields packed (no padding; so you probably
                                 // can't just compute over the bytes of the struct).
};

enum SecurityLevel : uint32_t {
    SOFTWARE = 0,
    TRUSTED_ENVIRONMENT = 1,
};

/**
 * Formats for key import and export.
 */
enum KeyFormat : uint32_t {
    X509 = 0,  /** for public key export */
    PKCS8 = 1, /** for asymmetric key pair import */
    RAW = 3,   /* for symmetric key import and export*/
};

typedef uint64_t OperationHandle;

所以描述部分,主要说明密钥的规范和使用限制。类似生成密钥是的那些参数。

其他的几个字段,大家可以看官方文档的描述。有空我继续补充。

最后补充下,key被导入进行的流程:

 1. Get the private key material for wrappingKeyBlob, verifying that the wrapping key has
     *        purpose KEY_WRAP, padding mode RSA_OAEP, and digest SHA_2_256, returning the
     *        appropriate error if any of those requirements fail.
     * 
     *     2. Extract the encryptedTransportKey field from the SecureKeyWrapper, and decrypt
     *        it with the wrapping key.
     * rsa 解密出aes key
     *     3. XOR the result of step 2 with maskingKey.
     * 异或mask key
     *     4. Use the result of step 3 as an AES-GCM key to decrypt encryptedKey, using the encoded
     *        value of keyDescription as the additional authenticated data.  Call the result
     *        "keyData" for the next step.
     * 异或出来的密钥使用AES-GCM  解密
     *     5. Perform the equivalent of calling importKey(keyParams, keyFormat, keyData), except
     *        that the origin tag should be set to SECURELY_IMPORTED.

这里mask key没有地方保存,我在Android 11的源码里面找到的

 byte[] maskingKey = new byte[32];

使用的时候请注意。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android上使用ASN.1编解码,可以采用Bouncy Castle库提供的API实现。 首先,需要在项目中导入Bouncy Castle库,可以通过Gradle添加以下依赖: ``` implementation 'org.bouncycastle:bcprov-jdk15on:1.68' implementation 'org.bouncycastle:bcpkix-jdk15on:1.68' ``` 接下来,可以使用Bouncy Castle提供的ASN.1编解码API实现对ASN.1格式数据的编解码。下面是一个简单的示例代码: ```java import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; public class ASN1Util { /** * 将ASN.1格式数据编码为字节数组 * * @param data 编码前的数据 * @return 编码后的数据 * @throws IOException */ public static byte[] encode(byte[] data) throws IOException { // 构造ASN.1格式数据 DERSequence seq = new DERSequence(new ASN1Primitive[]{ new DERInteger(123), new DEROctetString(data) }); // 将ASN.1格式数据编码为字节数组 ByteArrayOutputStream baos = new ByteArrayOutputStream(); ASN1OutputStream os = new ASN1OutputStream(baos); os.writeObject(seq); os.close(); return baos.toByteArray(); } /** * 将字节数组解码为ASN.1格式数据 * * @param encodedData 编码后的数据 * @return 解码后的数据 * @throws IOException */ public static byte[] decode(byte[] encodedData) throws IOException { // 将字节数组解码为ASN.1格式数据 ByteArrayInputStream bais = new ByteArrayInputStream(encodedData); ASN1InputStream is = new ASN1InputStream(bais); DERSequence seq = (DERSequence) is.readObject(); is.close(); // 解析ASN.1格式数据 int intValue = ((DERInteger) seq.getObjectAt(0)).getValue().intValue(); byte[] data = ((DEROctetString) seq.getObjectAt(1)).getOctets(); return data; } } ``` 上述代码中,ASN1Util类提供了encode和decode方法,分别用于将ASN.1格式数据编码为字节数组和将字节数组解码为ASN.1格式数据。在encode方法中,首先构造了一个ASN.1格式的序列,包含一个整数和一个字节数组,然后使用ASN1OutputStream将序列编码为字节数组;在decode方法中,首先使用ASN1InputStream将字节数组解码为ASN.1格式数据,然后解析ASN.1格式数据,获取整数和字节数组。 使用示例: ```java byte[] data = "hello, world!".getBytes(); byte[] encodedData = ASN1Util.encode(data); byte[] decodedData = ASN1Util.decode(encodedData); System.out.println(new String(decodedData)); // 输出:hello, world! ``` 这样,就可以使用Bouncy Castle库在Android上实现ASN.1编解码了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值