Some fixes for generating and getting public key

This commit is contained in:
Vladimir Privezenov
2025-12-27 23:48:42 +03:00
parent ce3fdfdf8a
commit 9a2ad514db
7 changed files with 97 additions and 28 deletions

View File

@ -30,6 +30,7 @@ CWebCrypto.prototype.getRandomValues = function(length) {
}
CWebCrypto.prototype.getAesKey = function(masterPassword, pbkdfParams) {
const oThis = this;
const aesKeyGenParams = new AesGcmKeyGenParams();
return this.subtle.importKey(
'raw',
masterPassword,
@ -37,7 +38,6 @@ CWebCrypto.prototype.getAesKey = function(masterPassword, pbkdfParams) {
false,
['deriveKey']
).then(function(pwKey) {
const aesKeyGenParams = new AesGcmKeyGenParams();
return oThis.subtle.deriveKey(
pbkdfParams.getCryptoParams(),
pwKey,
@ -46,7 +46,7 @@ CWebCrypto.prototype.getAesKey = function(masterPassword, pbkdfParams) {
['encrypt', 'decrypt']
);
}).then(function(aesKey) {
return WebSymmetricKey.fromCryptoKey(aesKey, pbkdfParams);
return WebSymmetricKey.fromCryptoKey(aesKey, aesKeyGenParams.getImportParams());
});
};
CWebCrypto.prototype.sign = function(key, data) {
@ -71,9 +71,10 @@ CWebCrypto.prototype.decrypt = function(key, data) {
}
CWebCrypto.prototype.encrypt = function(key, data) {
const cryptoKey = key.getCryptoKey();
const algorithm = key.getEncryptParams();
const encryptParams = key.getEncryptParams();
const algorithm = encryptParams.getCryptoParams();
return this.subtle.encrypt(algorithm, cryptoKey, data).then(function (encryptedData) {
const data = new EncryptData(encryptedData, algorithm);
const data = new EncryptData(encryptedData, encryptParams);
const writer = new BinaryWriter();
data.export(writer);
return writer.GetData();

View File

@ -1,4 +1,4 @@
import {CryptoBase, initClass} from "./utils";
import {CryptoBase, initClass, isEqualArrays} from "./utils";
import {c_oAscExportKeyFormat, c_oAscKeyStorageType} from "./defines";
import {BinaryWriter, writeBool, writeBuffer, writeLong, writeObject, writeString} from "./serialize/writer";
import {getCrypto} from "./crypto";
@ -13,7 +13,7 @@ function CryptoKeyBase() {
this.params = null;
this.type = c_oAscKeyStorageType.NoType;
}
initClass(CryptoBase, CryptoKeyBase);
initClass(CryptoKeyBase, CryptoBase);
CryptoKeyBase.import = function(reader, version, symmetricKey) {};
CryptoKeyBase.prototype.init = function() {
const crypto = getCrypto();
@ -111,15 +111,21 @@ WebKeyPair.prototype.setPrivateKey = function(privateKey) {
WebKeyPair.fromCryptoBuffer = function(publicKeyBuffer, privateKeyBuffer, importParams) {
const keyPair = new this();
keyPair.init();
const publicKey = new WebPublicKey();
const publicKey = new (this.getPublicKeyConstructor())();
publicKey.setBinaryKey(publicKeyBuffer);
const privateKey = new WebPrivateKey();
const privateKey = new (this.getPrivateKeyConstructor())();
privateKey.setBinaryKey(privateKeyBuffer);
keyPair.setPublicKey(publicKey);
keyPair.setPrivateKey(privateKey);
keyPair.setParams(importParams);
return keyPair;
};
WebKeyPair.getPublicKeyConstructor = function() {
return WebPublicKey;
};
WebKeyPair.getPrivateKeyConstructor = function() {
return WebPrivateKey;
};
WebKeyPair.prototype.initKey = function (aesKey) {
const crypto = getCrypto();
return Promise.all([crypto.initKey(this.publicKey), crypto.initKey(this.privateKey, aesKey)]);
@ -129,7 +135,7 @@ WebKeyPair.prototype.isHavePublicKey = function(publicKey) {
};
WebKeyPair.prototype.getExportPublicKey =function() {
const writer = new BinaryWriter();
this.publicKey.export(writer);
writeObject(writer, this.publicKey);
return writer.GetData();
};
WebKeyPair.prototype.changeMasterPassword = function(oldAesKey, newAesKey) {
@ -141,6 +147,12 @@ export function WebSignKeyPair() {
initClass(WebSignKeyPair, WebKeyPair, c_oAscKeyStorageType.WebSignKeyPair);
WebSignKeyPair.import = WebKeyPair.import;
WebSignKeyPair.fromCryptoBuffer = WebKeyPair.fromCryptoBuffer;
WebSignKeyPair.getPublicKeyConstructor = function() {
return WebPublicSignKey;
};
WebSignKeyPair.getPrivateKeyConstructor = function() {
return WebPrivateSignKey;
};
WebEncryptKeyPair.prototype.verify = function (data) {
return this.publicKey.verify(data);
};
@ -156,6 +168,12 @@ export function WebEncryptKeyPair() {
initClass(WebEncryptKeyPair, WebKeyPair, c_oAscKeyStorageType.WebEncryptKeyPair);
WebEncryptKeyPair.import = WebKeyPair.import;
WebEncryptKeyPair.fromCryptoBuffer = WebKeyPair.fromCryptoBuffer;
WebEncryptKeyPair.getPublicKeyConstructor = function() {
return WebPublicEncryptKey;
};
WebEncryptKeyPair.getPrivateKeyConstructor = function() {
return WebPrivateEncryptKey;
};
WebEncryptKeyPair.prototype.encrypt = function (data) {
return this.publicKey.encrypt(data);
};
@ -164,14 +182,15 @@ WebEncryptKeyPair.prototype.decrypt = function (data) {
};
function AsymmetricKey() {
CryptoBase.call(this);
this.binaryKey = null;
this.cryptoKey = null;
this.version = 1;
this.params = null;
this.type = c_oAscKeyStorageType.NoType;
}
initClass(AsymmetricKey, CryptoBase);
AsymmetricKey.prototype.setBinaryKey = function(binaryKey) {
this.binaryKey = binaryKey;
this.binaryKey = new Uint8Array(binaryKey);
};
AsymmetricKey.prototype.setCryptoKey = function(cryptoKey) {
this.cryptoKey = cryptoKey;
@ -252,6 +271,7 @@ export function WebPrivateSignKey() {
WebPrivateKey.call(this);
}
initClass(WebPrivateSignKey, WebPrivateKey, c_oAscKeyStorageType.WebPrivateSignKey);
WebPrivateSignKey.import = WebPrivateKey.import;
WebPrivateSignKey.prototype.getCryptoUsages = function () {
return ["sign"];
};
@ -260,14 +280,13 @@ export function WebPrivateEncryptKey() {
WebPrivateKey.call(this);
}
initClass(WebPrivateEncryptKey, WebPrivateKey, c_oAscKeyStorageType.WebPrivateEncryptKey);
WebPrivateEncryptKey.import = WebPrivateKey.import;
WebPrivateEncryptKey.prototype.getCryptoUsages = function () {
return ["decrypt"];
};
function WebPublicKey() {
AsymmetricKey.call(this);
this.binaryKey = null;
this.cryptoKey = null;
}
initClass(WebPublicKey, AsymmetricKey);
@ -308,13 +327,14 @@ WebPublicKey.prototype.getImportFormat = function () {
return c_oAscExportKeyFormat.spki;
}
WebPublicKey.prototype.isEqual = function (publicKey) {
return this.binaryKey === publicKey.binaryKey;
return isEqualArrays(this.binaryKey, publicKey.binaryKey);
};
export function WebPublicSignKey() {
WebPublicKey.call(this);
}
initClass(WebPublicSignKey, WebPublicKey, c_oAscKeyStorageType.WebPublicSignKey);
WebPublicSignKey.import = WebPublicKey.import;
WebPublicSignKey.prototype.getCryptoUsages = function () {
return ["verify"];
};
@ -323,6 +343,7 @@ export function WebPublicEncryptKey() {
WebPublicKey.call(this);
}
initClass(WebPublicEncryptKey, WebPublicKey, c_oAscKeyStorageType.WebPublicEncryptKey);
WebPublicEncryptKey.import = WebPublicKey.import;
WebPublicEncryptKey.prototype.getCryptoUsages = function () {
return ["encrypt"];
};
@ -333,7 +354,7 @@ export function WebSymmetricKey() {
this.cryptoKey = null;
this.binaryKey = null;
}
initClass(WebSymmetricKey, AsymmetricKey, c_oAscKeyStorageType.WebSymmetricKey);
initClass(WebSymmetricKey, CryptoKeyBase, c_oAscKeyStorageType.WebSymmetricKey);
WebSymmetricKey.import = function(reader) {
const symmetricKey = new WebSymmetricKey();
@ -366,7 +387,7 @@ WebSymmetricKey.fromCryptoKey = function(cryptoKey, pbkdfParams) {
return key;
};
WebSymmetricKey.prototype.setBinaryKey = function(buffer) {
this.binaryKey = buffer;
this.binaryKey = new Uint8Array(buffer);
};
WebSymmetricKey.prototype.getBinaryKey = function() {
return this.binaryKey;
@ -426,7 +447,10 @@ WebSymmetricKey.prototype.changeMasterPassword = function(oldAesKey, newAesKey)
}).then(function(encryptedKey) {
oThis.binaryKey = encryptedKey;
});
}
};
WebSymmetricKey.prototype.getEncryptParams = function() {
return this.params.getEncryptParams();
};
export function EncryptData(encryptData, params) {
CryptoBase.call(this);

View File

@ -42,6 +42,9 @@ AlgorithmParams.prototype.export = function(writer) {
}
}
};
AlgorithmParams.prototype.isSign = function() {
return false;
};
function RsaImportParams(hash) {
AlgorithmParams.call(this);
@ -106,7 +109,7 @@ RsaKeyGenParams.prototype.getCryptoUsages = function() {
export function RsaOAEPKeyGenParams(hash, modulusLength, publicExponent) {
RsaKeyGenParams.call(this, hash, modulusLength, publicExponent);
}
initClass(RsaOAEPImportParams, RsaKeyGenParams, c_oAscKeyStorageType.RSAOAEPKeyGenParams);
initClass(RsaOAEPKeyGenParams, RsaKeyGenParams, c_oAscKeyStorageType.RSAOAEPKeyGenParams);
RsaOAEPKeyGenParams.prototype.getCryptoUsages = function() {
return ['encrypt', 'decrypt'];
};
@ -177,15 +180,27 @@ AesGcmCryptoParams.prototype.init = function () {
this.iv = getRandomValues(12);
this.tagLength = 128;
};
AesGcmCryptoParams.prototype.getCryptoParams = function() {
return {
name: "AES-GCM",
iv: this.iv,
tagLength: this.tagLength
}
};
function AesImportParams() {
AlgorithmParams.call(this);
}
initClass(AesImportParams, AlgorithmParams);
function AesKeyGenParams(length) {
AlgorithmParams.call(this);
AesImportParams.call(this);
this.length = length;
}
initClass(AesKeyGenParams, AlgorithmParams);
initClass(AesKeyGenParams, AesImportParams);
AesKeyGenParams.prototype.getImportParams = function() {
return new AlgorithmParams();
return new AesImportParams();
};
AesKeyGenParams.prototype.getKeyGenCryptoParams = function() {
return {
@ -197,10 +212,23 @@ AesKeyGenParams.prototype.getCryptoUsages = function() {
return ['encrypt', 'decrypt'];
};
function AesGcmImportParams() {
AesImportParams.call(this);
}
initClass(AesGcmImportParams, AesImportParams);
AesGcmImportParams.prototype.getEncryptParams = function() {
const cryptoParams = new AesGcmCryptoParams();
cryptoParams.init();
return cryptoParams;
};
export function AesGcmKeyGenParams() {
AesKeyGenParams.call(this, 256);
}
initClass(AesGcmKeyGenParams, AesKeyGenParams, c_oAscKeyStorageType.AesGCMKeyGenParams);
AesGcmKeyGenParams.prototype.getImportParams = function() {
return new AesGcmImportParams();
};
export const PBKDFSaltLength = 16;
export function PBKDF2Params(isInit) {

View File

@ -16,4 +16,19 @@ export function initClass(fClass, fBase, type) {
export function getRandomValues(length) {
const crypto = getCrypto();
return crypto.getRandomValues(length);
}
export function isEqualArrays(array1, array2) {
if (!array1 && array2 || array1 && !array2) {
return false;
}
if (array1.length !== array2.length) {
return false;
}
for (let i = 0; i < array1.length; i += 1) {
if (array1[i] !== array2[i]) {
return false;
}
}
return true;
}

View File

@ -22,20 +22,19 @@ generateKeyButton.addEventListener('click', (e) => {
});
getKeyButton.addEventListener('click', (e) => {
storageManager.getKeyByPublicKey(Uint8Array.fromBase64(publicKeyInput.textContent)).then(function (key) {
selectedKeyDiv.textContent = key.getExportPublicKey().toBase64();
selectedKey = key;
});
const key = storageManager.getKeyByPublicKey(Uint8Array.fromBase64(publicKeyInput.value))
selectedKeyDiv.textContent = key.getExportPublicKey().toBase64();
selectedKey = key;
});
encryptKeyButton.addEventListener('click', (e) => {
selectedKey.encrypt(dataInput.textContent).then(function (binaryData) {
selectedKey.encrypt(dataInput.value).then(function (binaryData) {
encryptedDataDiv.textContent = binaryData.toBase64();
});
});
decryptKeyButton.addEventListener('click', (e) => {
selectedKey.decrypt(Uint8Array.fromBase64(encryptDataInput.textContent)).then(function (binaryData) {
selectedKey.decrypt(Uint8Array.fromBase64(encryptDataInput.value)).then(function (binaryData) {
decryptedDataDiv.textContent = binaryData.toBase64();
});
});

View File

@ -11,6 +11,7 @@ StorageManager.prototype.generateAsymmetricKey = function () {
return oThis.keyStorage.generateKey(new RsaOAEPKeyGenParams(c_oAscDigestType.SHA256), masterPassword.toUtf8());
}).then(function (key) {
oThis.keyStorage.addKeys([key]);
return key;
});
};
StorageManager.prototype.getMasterPassword = function () {

View File

@ -13,6 +13,7 @@ export default defineConfig({
output: {
generatedCode: "es5"
}
}
},
minify: false
},
})