import * as asn1js from "asn1js"; import * as pvutils from "pvutils"; import * as common from "./common"; import { AlgorithmIdentifier, AlgorithmIdentifierJson, AlgorithmIdentifierSchema } from "./AlgorithmIdentifier"; import { ECPublicKey } from "./ECPublicKey"; import { RSAPublicKey } from "./RSAPublicKey"; import * as Schema from "./Schema"; import { PkiObject, PkiObjectParameters } from "./PkiObject"; import { AsnError } from "./errors"; import { EMPTY_STRING } from "./constants";
export type PublicKeyInfoSchema = Schema.SchemaParameters<{
algorithm?: AlgorithmIdentifierSchema;
subjectPublicKey?: string;
}>;
/** * Represents the PublicKeyInfo structure described in [RFC5280](https://datatracker.ietf.org/doc/html/rfc5280)
*/
export class PublicKeyInfo extends PkiObject implements IPublicKeyInfo {
public algorithm!: AlgorithmIdentifier; public subjectPublicKey!: asn1js.BitString; private _parsedKey?: ECPublicKey | RSAPublicKey | null; public get parsedKey(): ECPublicKey | RSAPublicKey | undefined { if (this._parsedKey === undefined) { switch (this.algorithm.algorithmId) { // TODO Use fabric case"1.2.840.10045.2.1": // ECDSA if ("algorithmParams" in this.algorithm) { if (this.algorithm.algorithmParams.constructor.blockName() === asn1js.ObjectIdentifier.blockName()) { try { this._parsedKey = new ECPublicKey({
namedCurve: this.algorithm.algorithmParams.valueBlock.toString(),
schema: this.subjectPublicKey.valueBlock.valueHexView
});
} catch (ex) { // nothing
} // Could be a problems during recognition of internal public key data here. Let's ignore them.
}
} break; case"1.2.840.113549.1.1.1": // RSA
{ const publicKeyASN1 = asn1js.fromBER(this.subjectPublicKey.valueBlock.valueHexView); if (publicKeyASN1.offset !== -1) { try { this._parsedKey = new RSAPublicKey({ schema: publicKeyASN1.result });
} catch (ex) { // nothing
} // Could be a problems during recognition of internal public key data here. Let's ignore them.
}
} break; default:
}
this._parsedKey ||= null;
}
returnthis._parsedKey || undefined;
} public set parsedKey(value: ECPublicKey | RSAPublicKey | undefined) { this._parsedKey = value;
}
/** * Initializes a new instance of the {@link PublicKeyInfo} class * @param parameters Initialization parameters
*/
constructor(parameters: PublicKeyInfoParameters = {}) { super();
if (parameters.json) { this.fromJSON(parameters.json);
}
if (parameters.schema) { this.fromSchema(parameters.schema);
}
}
/** * Returns default values for all class members * @param memberName String name for a class member * @returns Default value
*/ publicstatic override defaultValues(memberName: typeof ALGORITHM): AlgorithmIdentifier; publicstatic override defaultValues(memberName: typeof SUBJECT_PUBLIC_KEY): asn1js.BitString; publicstatic override defaultValues(memberName: string): any { switch (memberName) { case ALGORITHM: returnnew AlgorithmIdentifier(); case SUBJECT_PUBLIC_KEY: returnnew asn1js.BitString(); default: returnsuper.defaultValues(memberName);
}
}
//#region Get internal properties from parsed schema this.algorithm = new AlgorithmIdentifier({ schema: asn1.result.algorithm }); this.subjectPublicKey = asn1.result.subjectPublicKey; //#endregion
}
public toSchema(): asn1js.Sequence { return (new asn1js.Sequence({
value: [ this.algorithm.toSchema(), this.subjectPublicKey
]
}));
}
public toJSON(): PublicKeyInfoJson | JsonWebKey { //#region Return common value in case we do not have enough info fo making JWK if (!this.parsedKey) { return {
algorithm: this.algorithm.toJSON(),
subjectPublicKey: this.subjectPublicKey.toJSON(),
};
} //#endregion
/** * Converts JSON value into current object * @param json JSON object
*/ public fromJSON(json: any): void { if ("kty" in json) { switch (json.kty.toUpperCase()) { case"EC": this.parsedKey = new ECPublicKey({ json });
this.algorithm = new AlgorithmIdentifier({
algorithmId: "1.2.840.10045.2.1",
algorithmParams: new asn1js.ObjectIdentifier({ value: this.parsedKey.namedCurve })
}); break; case"RSA": this.parsedKey = new RSAPublicKey({ json });
this.algorithm = new AlgorithmIdentifier({
algorithmId: "1.2.840.113549.1.1.1",
algorithmParams: new asn1js.Null()
}); break; default: thrownew Error(`Invalid value for"kty" parameter: ${json.kty}`);
}
this.subjectPublicKey = new asn1js.BitString({ valueHex: this.parsedKey.toSchema().toBER(false) });
}
}
public async importKey(publicKey: CryptoKey, crypto = common.getCrypto(true)): Promise<void> { try { if (!publicKey) { thrownew Error("Need to provide publicKey input parameter");
}
const exportedKey = await crypto.exportKey("spki", publicKey); const asn1 = asn1js.fromBER(exportedKey); try { this.fromSchema(asn1.result);
} catch (exception) { thrownew Error("Error during initializing object from schema");
}
} catch (e) { const message = e instanceof Error ? e.message : `${e}`; thrownew Error(`Error during exporting public key: ${message}`);
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-06)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.