SubtleCrypto: importKey() メソッド
==============================

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

**`importKey()`** は `SubtleCrypto` インターフェイスのメソッドで、鍵をインポートします。つまり、外部のポータブル形式の鍵を入力として取り、ウェブ暗号 API で使用できる `CryptoKey` オブジェクトを返します。

この関数はいくつかのインポート形式を受け入れます。詳細は対応している形式を参照してください。

構文
--


```js
importKey(format, keyData, algorithm, extractable, keyUsages)
```

### 引数

`format`

インポートする鍵のデータ形式を記述する文字列。以下のいずれかになります。

* `raw`: Raw 形式です。
* `pkcs8`: PKCS #8 形式です。
* `spki`: SubjectPublicKeyInfo 形式です。
* `jwk`: JSON Web Key 形式です。

`keyData`

`ArrayBuffer`、TypedArray、 `DataView`、または指定された形式で鍵を格納した `JSONWebKey` オブジェクトです。

`algorithm`

インポートする鍵の種類を定義し、アルゴリズム固有の追加引数を提供するオブジェクトです。

* RSASSA-PKCS1-v1\_5, RSA-PSS, RSA-OAEP の場合:
 `RsaHashedImportParams` (en-US) オブジェクトを渡してください。
* ECDSA または ECDH の場合:
 `EcKeyImportParams` (en-US) オブジェクトを渡してください。
* HMAC の場合:
 `HmacImportParams` (en-US) オブジェクトを渡してください。
* AES-CTR, AES-CBC,
 AES-GCM, AES-KW の場合:
 アルゴリズムを識別する文字列、または `{ "name": ALGORITHM }` の形のオブジェクト。 `ALGORITHM` はアルゴリズム名です。
* PBKDF2 の場合: 文字列 `PBKDF2` を渡してください。
* HKDF の場合: 文字列 `HKDF` を渡してください。

`extractable`

論理値で、 `SubtleCrypto.exportKey()` または `SubtleCrypto.wrapKey()` を使用して鍵をエクスポートすることが可能かどうかを示します。

`keyUsages`

その鍵で何ができるかを示す `Array` です。鍵の使用は 使用可能な値は以下の通りです。

* `encrypt`: この鍵はメッセージの暗号化で使用することができます。
* `decrypt`: この鍵はメッセージの復号で使用することができます。
* `sign`: この鍵はメッセージの署名で使用することができます。
* `verify`: この鍵は署名の検証で使用することができます。
* `deriveKey`: この鍵は新しい鍵の導出で使用することができます。
* `deriveBits`: この鍵はビットの導出で使用することができます。
* `wrapKey`: この鍵は鍵をラップするのに使用することができます。
* `unwrapKey`: この鍵は鍵のラップを解除するのに使用することができます。

### 返値

インポートされた鍵を `CryptoKey` オブジェクトとして履行される `Promise` です。

### 例外

以下の例外が発生した場合、プロミスは拒否されます。

`SyntaxError` `DOMException`

`keyUsages` が空で、ラップされていない鍵の種類が `secret` または `private` である場合に発生します。

`TypeError`

無効な形式を使用しようとした場合や `keyData` がその形式に適していない場合に発生します。

対応している形式
--------

この API は、4 つの異なる鍵形式、Raw、PKCS #8、SubjectPublicKeyInfo、JSON ウェブ鍵のインポート/エクスポートに対応しています。

### Raw

この形式を使用して、AES や HMAC 秘密鍵、楕円曲線公開鍵をインポートまたはエクスポートできます。

この形式では、鍵は鍵の生のバイトを格納した `ArrayBuffer` として提供されます。

### PKCS #8

この形式を使用して、RSA または楕円曲線秘密鍵をインポートまたはエクスポートできます。

PKCS #8 の形式は、RFC 5208で ASN.1 記法を用いて定義されています。
```

PrivateKeyInfo ::= SEQUENCE {
    version                   Version,
    privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
    privateKey                PrivateKey,
    attributes           [0]  IMPLICIT Attributes OPTIONAL }
```


`importKey()` メソッドは、このオブジェクトを `ArrayBuffer` に `PrivateKeyInfo` の DER エンコードされたものが入ったものとして受け取ることを期待します。 DER は ASN.1 構造体をバイナリー形式にエンコードするための一連のルールです。

このオブジェクトは PEM 形式で表示されることがほとんどです。 PEM 形式はバイナリーデータを ASCII でエンコードする方法です。ヘッダーとフッターで構成され、その間に base64 エンコードのバイナリーデータがあります。 PEM エンコードされた `PrivateKeyInfo` は次のようになります。
```

-----BEGIN PRIVATE KEY-----
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAU9BD0jxDfF5OV380z
9VIEUN2W5kJDZ3hbuaDenCxLiAMsoquKTfFaou71eLdN0TShZANiAARMUhCee/cp
xmjGc1roj0D0k6VlUqtA+JVCWigXcIAukOeTHCngZDKCrD4PkXDBvbciJdZKvO+l
ml2FIkoovZh/8yeTKmjUMb804g6OmjUc9vVojCRV0YdaSmYkkJMJbLg=
-----END PRIVATE KEY-----
```


これを `importKey()` に渡せる形式に取得するには、 2 つのことを行う必要があります。

* `window.atob()` を使用して、ヘッダーとフッターの間の部分を base64 デコードします。
* 結果の文字列を `ArrayBuffer` に変換します。

例の節を参照してください。

### SubjectPublicKeyInfo

この形式を使用して、 RSA または楕円曲線公開鍵をインポートまたはエクスポートできます。

`SubjectPublicKey` は RFC 5280, Section 4.1 において、 ASN.1 notation を使用して定義されています。
```

SubjectPublicKeyInfo  ::=  SEQUENCE  {
    algorithm            AlgorithmIdentifier,
    subjectPublicKey     BIT STRING  }
```


PKCS #8 と同様に、 `importKey()` メソッドはこのオブジェクトを `SubjectPublicKeyInfo` の DER エンコード形式のデータを格納した `ArrayBuffer` として受け取ることを期待します。

 繰り返しますが、このオブジェクトは PEM 形式で表示されることがほとんどです。
 PEM エンコードされた `SubjectPublicKeyInfo` は次のようになります：
```

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3j+HgSHUnc7F6XzvEbD0
r3M5JNy+/kabiJVu8IU1ERAl3Osi38VgiMzjDBDOrFxVzNNzl+SXAHwXIV5BHiXL
CQ6qhwYsDgH6OqgKIwiALra/wNH4UHxj1Or/iyAkjHRR/kGhUtjyVCjzvaQaDpJW
2G+syd1ui0B6kJov2CRUWiPwpff8hBfVWv8q9Yc2yD5hCnykVL0iAiyn+SDAk/rv
8dC5eIlzCI4efUCbyG4c9O88Qz7bS14DxSfaPTy8P/TWoihVVjLaDF743LgM/JLq
CDPUBUA3HLsZUhKm3BbSkd7Q9Ngkjv3+yByo4/fL+fkYRa8j9Ypa2N0Iw53LFb3B
gQIDAQAB
-----END PUBLIC KEY-----
```


PKCS #8 と同様に、これを `importKey()` に渡せる形式で取得するには、 2 つのことを行う必要があります。

* `window.atob()` を使用して、ヘッダーとフッターの間の部分を base64 デコードします。
* 結果の文字列を `ArrayBuffer` に変換します。

例節を参照してください。

### JSON ウェブ鍵

JSON ウェブ鍵形式を使用して、RSA または楕円曲線公開鍵や秘密鍵、AES や HMAC 秘密鍵をインポートまたはエクスポートできます。

 JSON ウェブ鍵形式は、RFC 7517で定義されています。
 公開鍵、秘密鍵、秘密鍵を JSON オブジェクトとして表す方法が記述されています。

JSON ウェブ鍵は次のようなものです（これは EC 秘密鍵です）。


```json
{
  "crv": "P-384",
  "d": "wouCtU7Nw4E8\_7n5C1-xBjB4xqSb\_liZhYMsy8MGgxUny6Q8NCoH9xSiviwLFfK\_",
  "ext": true,
  "key\_ops": ["sign"],
  "kty": "EC",
  "x": "SzrRXmyI8VWFJg1dPUNbFcc9jZvjZEfH7ulKI1UkXAltd7RGWrcfFxqyGPcwu6AQ",
  "y": "hHUag3OvDzEr0uUQND4PXHQTXP5IDGdYhJhL-WLKjnGjQAw0rNGy5V29-aV-yseW"
};
```

例
-

**メモ:** You can try the working examples on GitHub.

### Raw インポート

この例では、使用する生のバイトを格納した `ArrayBuffer` から AES 鍵をインポートします。完全なコードは GitHub で確認してください。


```js
const rawKey = window.crypto.getRandomValues(new Uint8Array(16));

/\*
Import an AES secret key from an ArrayBuffer containing the raw bytes.
Takes an ArrayBuffer string containing the bytes, and returns a Promise
that will resolve to a CryptoKey representing the secret key.
\*/
function importSecretKey(rawKey) {
  return window.crypto.subtle.importKey("raw", rawKey, "AES-GCM", true, [
    "encrypt",
    "decrypt",
  ]);
}
```

### PKCS #8 インポート

 この例では、PEM エンコードされた PKCS #8 オブジェクトから RSA 秘密鍵をインポートします。
 完全なコードは GitHub で確認してください。


```js
/\*
Convert a string into an ArrayBuffer
from https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
\*/
function str2ab(str) {
  const buf = new ArrayBuffer(str.length);
  const bufView = new Uint8Array(buf);
  for (let i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

const pemEncodedKey = `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDD0tPV/du2vftjvXj1t/gXTK39sNBVrOAEb/jKzXae+Xa0H+3LhZaQIQNMfACiBSgIfZUvEGb+7TqXWQpoLoFR/R7MvGWcSk98JyrVtveD8ZmZYyItSY7m2hcasqAFiKyOouV5vzyRe87/lEyzzBpF3bQQ4IDaQu+K9Hj5fKuU6rrOeOhsdnJc+VdDQLScHxvMoLZ9Vtt+oK9J4/tOLwr4CG8khDlBURcBY6gPcLo3dPU09SW+6ctX2cX4mkXx6O/0mmdTmacr/vu50KdRMleFeZYOWPAEhhMfywybTuzBiPVIZVP8WFCSKNMbfi1S9A9PdBqnebwwHhX3/hsEBt2BAgMBAAECggEABEI1P6nf6Zs7mJlyBDv+Pfl5rjL2cOqLy6TovvZVblMkCPpJyFuNIPDK2tK2i897ZaXfhPDBIKmllM2Hq6jZQKB110OAnTPDg0JxzMiIHPs32S1d/KilHjGff4Hjd4NXp1l1Dp8BUPOllorR2TYm2x6dcCGFw9lhTr8O03Qp4hjn84VjGIWADYCk83mgS4nRsnHkdiqYnWx1AjKlY51yEK6RcrDMi0Th2RXrrINoC35sVv+APt2rkoMGi52RwTEseA1KZGFrxjq61ReJif6p2VXEcvHeX6CWLx014LGk43z6Q28P6HgeEVEfIjyqCUea5Du/mYb/QsRSCosXLxBqwQKBgQD1+fdC9ZiMrVI+km7Nx2CKBn8rJrDmUh5SbXn2MYJdrUd8bYNnZkCgKMgxVXsvJrbmVOrby2txOiqudZkk5mD3E5O/QZWPWQLgRu8ueYNpobAX9NRgNfZ7rZD+81vh5MfZiXfuZOuzv29iZhU0oqyZ9y75eHkLdrerNkwYOe5aUQKBgQDLzapDi1NxkBgsj9iiO4KUa7jvD4JjRqFy4Zhj/jbQvlvM0F/uFp7sxVcHGx4r11C+6iCbhX4u+Zuu0HGjT4d+hNXmgGyxR8fIUVxOlOtDkVJa5sOBZK73/9/MBeKusdmJPRhalZQfMUJRWIoEVDMhfg3tW/rBj5RYAtP2dTVUMQKBgDs8yr52dRmT+BWXoFWwaWB0NhYHSFz/c8v4D4Ip5DJ5M5kUqquxJWksySGQa40sbqnD05fBQovPLU48hfgr/zghn9hUjBcsoZOvoZR4sRw0UztBvA+7jzOz1hKAOyWIulR6Vca0yUrNlJ6G5R56+sRNkiOETupi2dLCzcqb0PoxAoGAZyNHvTLvIZN4iGSrjz5qkM4LIwBIThFadxbv1fq6pt0O/BGf2o+cEdq0diYlGK64cEVwBwSBnSg4vzlBqRIAUejLjwEDAJyA4EE8Y5A9l04dzV7nJb5cRak6CrgXxay/mBJRFtaHxVlaZGxYPGSYE6UFS0+3EOmmevvDZQBf4qECgYEA0ZF6Vavz28+8wLO6SP3w8NmpHk7K9tGEvUfQ30SgDx4G7qPIgfPrbB4OP/E0qCfsIImi3sCPpjvUMQdVVZyPOIMuB+rV3ZOxkrzxEUOrpOpR48FZbL7RN90yRQsAsrp9e4iv8QwB3VxLe7X0TDqqnRyqrc/osGzuS2ZcHOKmCU8=
-----END PRIVATE KEY-----`;

/\*
Import a PEM encoded RSA private key, to use for RSA-PSS signing.
Takes a string containing the PEM encoded key, and returns a Promise
that will resolve to a CryptoKey representing the private key.
\*/
function importPrivateKey(pem) {
  // fetch the part of the PEM string between header and footer
  const pemHeader = "-----BEGIN PRIVATE KEY-----";
  const pemFooter = "-----END PRIVATE KEY-----";
  const pemContents = pem.substring(
    pemHeader.length,
    pem.length - pemFooter.length,
  );
  // base64 decode the string to get the binary data
  const binaryDerString = window.atob(pemContents);
  // convert from a binary string to an ArrayBuffer
  const binaryDer = str2ab(binaryDerString);

  return window.crypto.subtle.importKey(
    "pkcs8",
    binaryDer,
    {
      name: "RSA-PSS",
      hash: "SHA-256",
    },
    true,
    ["sign"],
  );
}
```

### SubjectPublicKeyInfo インポート

 この例では、PEM エンコードされた SubjectPublicKeyInfo オブジェクトから RSA 公開暗号化鍵をインポートします。
 完全なコードは GitHub で確認してください。


```js
// from https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
function str2ab(str) {
  const buf = new ArrayBuffer(str.length);
  const bufView = new Uint8Array(buf);
  for (let i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

const pemEncodedKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy3Xo3U13dc+xojwQYWoJLCbOQ5fOVY8LlnqcJm1W1BFtxIhOAJWohiHuIRMctv7dzx47TLlmARSKvTRjd0dF92jx/xY20Lz+DXp8YL5yUWAFgA3XkO3LSJgEOex10NB8jfkmgSb7QIudTVvbbUDfd5fwIBmCtaCwWx7NyeWWDb7A9cFxj7EjRdrDaK3ux/ToMLHFXVLqSL341TkCf4ZQoz96RFPUGPPLOfvN0x66CM1PQCkdhzjE6U5XGE964ZkkYUPPsy6Dcie4obhW4vDjgUmLzv0z7UD010RLIneUgDE2FqBfY/C+uWigNPBPkkQ+Bv/UigS6dHqTCVeD5wgyBQIDAQAB
-----END PUBLIC KEY-----`;

function importRsaKey(pem) {
  // fetch the part of the PEM string between header and footer
  const pemHeader = "-----BEGIN PUBLIC KEY-----";
  const pemFooter = "-----END PUBLIC KEY-----";
  const pemContents = pem.substring(
    pemHeader.length,
    pem.length - pemFooter.length - 1,
  );
  // base64 decode the string to get the binary data
  const binaryDerString = window.atob(pemContents);
  // convert from a binary string to an ArrayBuffer
  const binaryDer = str2ab(binaryDerString);

  return window.crypto.subtle.importKey(
    "spki",
    binaryDer,
    {
      name: "RSA-OAEP",
      hash: "SHA-256",
    },
    true,
    ["encrypt"],
  );
}
```

### JSON ウェブ鍵インポート

このコードは、 ECDSA 秘密署名鍵を指定された JSON ウェブ鍵オブジェクトにインポートします。完全なコードは GitHub で確認してください。


```js
const jwkEcKey = {
  crv: "P-384",
  d: "wouCtU7Nw4E8\_7n5C1-xBjB4xqSb\_liZhYMsy8MGgxUny6Q8NCoH9xSiviwLFfK\_",
  ext: true,
  key\_ops: ["sign"],
  kty: "EC",
  x: "SzrRXmyI8VWFJg1dPUNbFcc9jZvjZEfH7ulKI1UkXAltd7RGWrcfFxqyGPcwu6AQ",
  y: "hHUag3OvDzEr0uUQND4PXHQTXP5IDGdYhJhL-WLKjnGjQAw0rNGy5V29-aV-yseW",
};

/\*
Import a JSON Web Key format EC private key, to use for ECDSA signing.
Takes an object representing the JSON Web Key, and returns a Promise
that will resolve to a CryptoKey representing the private key.
\*/
function importPrivateKey(jwk) {
  return window.crypto.subtle.importKey(
    "jwk",
    jwk,
    {
      name: "ECDSA",
      namedCurve: "P-384",
    },
    true,
    ["sign"],
  );
}
```

仕様書
---

| Specification |
| --- |
| Web Cryptography API # SubtleCrypto-method-importKey |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* `SubtleCrypto.exportKey()`
* PKCS #8 形式.
* SubjectPublicKeyInfo 形式.
* JSON ウェブ鍵形式.