Move encryption/decryption to waller.ts
This commit is contained in:
parent
f108045d61
commit
8fc6023b8a
@ -9,9 +9,8 @@ import {
|
||||
Slip10RawIndex,
|
||||
stringToPath,
|
||||
xchacha20NonceLength,
|
||||
Xchacha20poly1305Ietf,
|
||||
} from "@cosmjs/crypto";
|
||||
import { fromBase64, fromHex, fromUtf8, toBase64, toHex, toUtf8 } from "@cosmjs/encoding";
|
||||
import { fromBase64, fromUtf8, toBase64, toHex, toUtf8 } from "@cosmjs/encoding";
|
||||
import { assert, isNonNullObject } from "@cosmjs/utils";
|
||||
|
||||
import { rawSecp256k1PubkeyToAddress } from "./address";
|
||||
@ -19,12 +18,16 @@ import { encodeSecp256k1Signature } from "./signature";
|
||||
import { StdSignature } from "./types";
|
||||
import {
|
||||
AccountData,
|
||||
decrypt,
|
||||
encrypt,
|
||||
EncryptionConfiguration,
|
||||
executeKdf,
|
||||
KdfConfiguration,
|
||||
makeCosmoshubPath,
|
||||
OfflineSigner,
|
||||
prehash,
|
||||
PrehashType,
|
||||
supportedAlgorithms,
|
||||
} from "./wallet";
|
||||
|
||||
const serializationTypeV1 = "secp256k1wallet-v1";
|
||||
@ -42,8 +45,6 @@ const basicPasswordHashingOptions: KdfConfiguration = {
|
||||
},
|
||||
};
|
||||
|
||||
const algorithmIdXchacha20poly1305Ietf = "xchacha20poly1305-ietf";
|
||||
|
||||
/**
|
||||
* This interface describes a JSON object holding the encrypted wallet and the meta data.
|
||||
* All fields in here must be JSON types.
|
||||
@ -54,14 +55,7 @@ export interface Secp256k1WalletSerialization {
|
||||
/** Information about the key derivation function (i.e. password to encryption key) */
|
||||
readonly kdf: KdfConfiguration;
|
||||
/** Information about the symmetric encryption */
|
||||
readonly encryption: {
|
||||
/**
|
||||
* An algorithm identifier, such as "xchacha20poly1305-ietf".
|
||||
*/
|
||||
readonly algorithm: string;
|
||||
/** A map of algorithm-specific parameters */
|
||||
readonly params: Record<string, unknown>;
|
||||
};
|
||||
readonly encryption: EncryptionConfiguration;
|
||||
/** An instance of Secp256k1WalletData, which is stringified, encrypted and base64 encoded. */
|
||||
readonly data: string;
|
||||
}
|
||||
@ -179,11 +173,10 @@ export class Secp256k1Wallet implements OfflineSigner {
|
||||
const untypedRoot: any = root;
|
||||
switch (untypedRoot.type) {
|
||||
case serializationTypeV1: {
|
||||
const nonce = fromHex(untypedRoot.encryption.params.nonce);
|
||||
const decryptedBytes = await Xchacha20poly1305Ietf.decrypt(
|
||||
const decryptedBytes = await decrypt(
|
||||
fromBase64(untypedRoot.data),
|
||||
encryptionKey,
|
||||
nonce,
|
||||
untypedRoot.encryption,
|
||||
);
|
||||
const decryptedDocument = JSON.parse(fromUtf8(decryptedBytes));
|
||||
const { mnemonic, accounts } = decryptedDocument;
|
||||
@ -299,18 +292,17 @@ export class Secp256k1Wallet implements OfflineSigner {
|
||||
),
|
||||
};
|
||||
const dataToEncryptRaw = toUtf8(JSON.stringify(dataToEncrypt));
|
||||
const nonce = Random.getBytes(xchacha20NonceLength);
|
||||
const encryptedData = await Xchacha20poly1305Ietf.encrypt(dataToEncryptRaw, encryptionKey, nonce);
|
||||
|
||||
const encryptionConfiguration: EncryptionConfiguration = {
|
||||
algorithm: supportedAlgorithms.xchacha20poly1305Ietf,
|
||||
params: { nonce: toHex(Random.getBytes(xchacha20NonceLength)) },
|
||||
};
|
||||
const encryptedData = await encrypt(dataToEncryptRaw, encryptionKey, encryptionConfiguration);
|
||||
|
||||
const out: Secp256k1WalletSerialization = {
|
||||
type: serializationTypeV1,
|
||||
kdf: kdfConfiguration,
|
||||
encryption: {
|
||||
algorithm: algorithmIdXchacha20poly1305Ietf,
|
||||
params: {
|
||||
nonce: toHex(nonce),
|
||||
},
|
||||
},
|
||||
encryption: encryptionConfiguration,
|
||||
data: toBase64(encryptedData),
|
||||
};
|
||||
return JSON.stringify(out);
|
||||
|
||||
@ -1,5 +1,12 @@
|
||||
import { Argon2id, Argon2idOptions, Sha256, Sha512, Slip10RawIndex } from "@cosmjs/crypto";
|
||||
import { toAscii } from "@cosmjs/encoding";
|
||||
import {
|
||||
Argon2id,
|
||||
Argon2idOptions,
|
||||
Sha256,
|
||||
Sha512,
|
||||
Slip10RawIndex,
|
||||
Xchacha20poly1305Ietf,
|
||||
} from "@cosmjs/crypto";
|
||||
import { fromHex, toAscii } from "@cosmjs/encoding";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
|
||||
import { StdSignature } from "./types";
|
||||
@ -84,3 +91,50 @@ export async function executeKdf(password: string, configuration: KdfConfigurati
|
||||
throw new Error("Unsupported KDF algorithm");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration how to encrypt data or how data was encrypted.
|
||||
* This is stored as part of the wallet serialization and must only contain JSON types.
|
||||
*/
|
||||
export interface EncryptionConfiguration {
|
||||
/**
|
||||
* An algorithm identifier, such as "xchacha20poly1305-ietf".
|
||||
*/
|
||||
readonly algorithm: string;
|
||||
/** A map of algorithm-specific parameters */
|
||||
readonly params: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export const supportedAlgorithms = {
|
||||
xchacha20poly1305Ietf: "xchacha20poly1305-ietf",
|
||||
};
|
||||
|
||||
export async function encrypt(
|
||||
plaintext: Uint8Array,
|
||||
encryptionKey: Uint8Array,
|
||||
config: EncryptionConfiguration,
|
||||
): Promise<Uint8Array> {
|
||||
switch (config.algorithm) {
|
||||
case supportedAlgorithms.xchacha20poly1305Ietf: {
|
||||
const nonce = fromHex((config.params as any).nonce);
|
||||
return Xchacha20poly1305Ietf.encrypt(plaintext, encryptionKey, nonce);
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported encryption algorithm: '${config.algorithm}'`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function decrypt(
|
||||
ciphertext: Uint8Array,
|
||||
encryptionKey: Uint8Array,
|
||||
config: EncryptionConfiguration,
|
||||
): Promise<Uint8Array> {
|
||||
switch (config.algorithm) {
|
||||
case supportedAlgorithms.xchacha20poly1305Ietf: {
|
||||
const nonce = fromHex((config.params as any).nonce);
|
||||
return Xchacha20poly1305Ietf.decrypt(ciphertext, encryptionKey, nonce);
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported encryption algorithm: '${config.algorithm}'`);
|
||||
}
|
||||
}
|
||||
|
||||
11
packages/sdk38/types/secp256k1wallet.d.ts
vendored
11
packages/sdk38/types/secp256k1wallet.d.ts
vendored
@ -1,6 +1,6 @@
|
||||
import { Slip10RawIndex } from "@cosmjs/crypto";
|
||||
import { StdSignature } from "./types";
|
||||
import { AccountData, KdfConfiguration, OfflineSigner, PrehashType } from "./wallet";
|
||||
import { AccountData, EncryptionConfiguration, KdfConfiguration, OfflineSigner, PrehashType } from "./wallet";
|
||||
/**
|
||||
* This interface describes a JSON object holding the encrypted wallet and the meta data.
|
||||
* All fields in here must be JSON types.
|
||||
@ -11,14 +11,7 @@ export interface Secp256k1WalletSerialization {
|
||||
/** Information about the key derivation function (i.e. password to encryption key) */
|
||||
readonly kdf: KdfConfiguration;
|
||||
/** Information about the symmetric encryption */
|
||||
readonly encryption: {
|
||||
/**
|
||||
* An algorithm identifier, such as "xchacha20poly1305-ietf".
|
||||
*/
|
||||
readonly algorithm: string;
|
||||
/** A map of algorithm-specific parameters */
|
||||
readonly params: Record<string, unknown>;
|
||||
};
|
||||
readonly encryption: EncryptionConfiguration;
|
||||
/** An instance of Secp256k1WalletData, which is stringified, encrypted and base64 encoded. */
|
||||
readonly data: string;
|
||||
}
|
||||
|
||||
25
packages/sdk38/types/wallet.d.ts
vendored
25
packages/sdk38/types/wallet.d.ts
vendored
@ -38,3 +38,28 @@ export interface KdfConfiguration {
|
||||
readonly params: Record<string, unknown>;
|
||||
}
|
||||
export declare function executeKdf(password: string, configuration: KdfConfiguration): Promise<Uint8Array>;
|
||||
/**
|
||||
* Configuration how to encrypt data or how data was encrypted.
|
||||
* This is stored as part of the wallet serialization and must only contain JSON types.
|
||||
*/
|
||||
export interface EncryptionConfiguration {
|
||||
/**
|
||||
* An algorithm identifier, such as "xchacha20poly1305-ietf".
|
||||
*/
|
||||
readonly algorithm: string;
|
||||
/** A map of algorithm-specific parameters */
|
||||
readonly params: Record<string, unknown>;
|
||||
}
|
||||
export declare const supportedAlgorithms: {
|
||||
xchacha20poly1305Ietf: string;
|
||||
};
|
||||
export declare function encrypt(
|
||||
plaintext: Uint8Array,
|
||||
encryptionKey: Uint8Array,
|
||||
config: EncryptionConfiguration,
|
||||
): Promise<Uint8Array>;
|
||||
export declare function decrypt(
|
||||
ciphertext: Uint8Array,
|
||||
encryptionKey: Uint8Array,
|
||||
config: EncryptionConfiguration,
|
||||
): Promise<Uint8Array>;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user