RSAVerify.mjs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /**
  2. * @author Matt C [me@mitt.dev]
  3. * @copyright Crown Copyright 2020
  4. * @license Apache-2.0
  5. */
  6. import Operation from "../Operation.mjs";
  7. import OperationError from "../errors/OperationError.mjs";
  8. import forge from "node-forge/dist/forge.min.js";
  9. import { MD_ALGORITHMS } from "../lib/RSA.mjs";
  10. /**
  11. * RSA Verify operation
  12. */
  13. class RSAVerify extends Operation {
  14. /**
  15. * RSAVerify constructor
  16. */
  17. constructor() {
  18. super();
  19. this.name = "RSA Verify";
  20. this.module = "Ciphers";
  21. this.description = "Verify a message against a signature and a public PEM encoded RSA key.";
  22. this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
  23. this.inputType = "byteArray";
  24. this.outputType = "string";
  25. this.args = [
  26. {
  27. name: "RSA Public Key (PEM)",
  28. type: "text",
  29. value: "-----BEGIN RSA PUBLIC KEY-----"
  30. },
  31. {
  32. name: "Message",
  33. type: "text",
  34. value: ""
  35. },
  36. {
  37. name: "Message Digest Algorithm",
  38. type: "option",
  39. value: Object.keys(MD_ALGORITHMS)
  40. }
  41. ];
  42. }
  43. /**
  44. * @param {byteArray} input
  45. * @param {Object[]} args
  46. * @returns {string}
  47. */
  48. run(input, args) {
  49. const [pemKey, message, mdAlgo] = args;
  50. if (pemKey.replace("-----BEGIN RSA PUBLIC KEY-----", "").length === 0) {
  51. throw new OperationError("Please enter a public key.");
  52. }
  53. try {
  54. // Load public key
  55. const pubKey = forge.pki.publicKeyFromPem(pemKey);
  56. // Generate message digest
  57. const md = MD_ALGORITHMS[mdAlgo].create();
  58. md.update(message, "utf8");
  59. // Compare signed message digest and generated message digest
  60. const result = pubKey.verify(md.digest().bytes(), input);
  61. return result ? "Verified OK" : "Verification Failure";
  62. } catch (err) {
  63. if (err.message === "Encrypted message length is invalid.") {
  64. throw new OperationError(`Signature length (${err.length}) does not match expected length based on key (${err.expected}).`);
  65. }
  66. throw new OperationError(err);
  67. }
  68. }
  69. }
  70. export default RSAVerify;