簡體   English   中英

打字稿文件中的Nodejs加密

[英]Nodejs crypto in typescript file

我創建了自己的 hash.js 文件,該文件需要加密並導出兩個使用加密的函數。 當我散列密碼時,它在我的 api.js 文件中工作正常。 但是現在我試圖在我的 user.service.ts 文件中導入這個文件,以便我可以將密碼的散列版本作為查詢參數而不是密碼本身發送。 當我嘗試這樣做時,我總是收到一個 TypeScript 錯誤,告訴我加密使用的函數不是函數。 但是我仍然可以控制台記錄我導入的對象,它對我來說看起來是合法的。 我查看了 node_modules 文件夾中的其他 java 腳本文件,但看不到我的文件有什么問題。

我還發現似乎需要創建一些定義文件,但我也曾多次嘗試創建這樣的文件,但似乎沒有任何效果

幾個小時的谷歌搜索以及缺乏時間在這個項目上缺乏知識導致我這篇文章,這是我的第一個stackoverflow帖子,我希望它不會不清楚,我很高興提供任何需要幫助我的信息解決這個問題。

來自控制台的錯誤代碼

LoginComponent.html:18 ERROR TypeError: crypto.randomBytes is not a function
at Object.genRandomString (hash.js:12)
at UserService.loginUser (user.service.ts:82)
at LoginComponent.getUser (login.component.ts:54)
at LoginComponent.onSubmit (login.component.ts:44)
at Object.eval [as handleEvent] (LoginComponent.html:18)
at handleEvent (core.es5.js:12014)
at callWithDebugContext (core.es5.js:13475)
at Object.debugHandleEvent [as handleEvent] (core.es5.js:13063)
at dispatchEvent (core.es5.js:8607)
at core.es5.js:10775

LoginComponent.html:18 ERROR CONTEXT DebugContext_ {view: {…}, nodeIndex: 31, nodeDef: {…}, elDef: {…}, elView: {…}}

hash.js 文件

'use strict'; var crypto = require('crypto'); /** * generates random string of characters i.e salt * @function * @param {number} length - Length of the random string. */ function genRandomString (length){ return crypto.randomBytes(Math.ceil(length/2)) .toString('hex') /** convert to hexadecimal format */ .slice(0,length); /** return required number of characters */ }; /** * hash password with sha512. * @function * @param {string} password - List of required fields. * @param {string} salt - Data to be validated. */ function sha512(password, salt){ var hash = crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ hash.update(password); var value = hash.digest('hex'); return { salt:salt, passwordHash:value }; }; module.exports = { genRandomString: genRandomString, sha512: sha512 };

混合 JavaScript 和 TypeScript 似乎有些混亂,但由於我自己遇到了這個問題,因此我是這樣解決它的。

首先,你的 hash.js 文件應該是 hash.ts。 然后你就可以導入crypto並正常使用了。 相關代碼如下:

import * as crypto from "crypto";

  public setEncryptionKeyDES(sKey: string) {
    const desIV = Buffer.alloc(8);
    this.encLobby.cipher = crypto.createCipheriv(
      "des-cbc",
      Buffer.from(sKey, "hex"),
      desIV,
    );
    this.encLobby.cipher.setAutoPadding(false);
    this.encLobby.decipher = crypto.createDecipheriv(
      "des-cbc",
      Buffer.from(sKey, "hex"),
      desIV,
    );
    this.encLobby.decipher.setAutoPadding(false);

    this.isSetupComplete = true;
  }

Edit1:從下面添加@attdona 的答案,確保您也將@types/node安裝到您的項目中,否則您將收到許多與找不到節點模塊相關的錯誤。

剛剛遇到這個問題(節點 v13.12.0,tsc v3.8.3)。 在我的情況下,導入:

import * as crypto from "crypto";

給出錯誤:

error TS2307: Cannot find module 'crypto'

因為我必須為節點安裝類型定義:它包括加密環境聲明。

npm install @types/node

注意:如果您有@types/node的全局安裝,那么您必須使用--typesRoot選項顯式聲明@types所在的路徑。 有關詳細信息,請參見此處

當我嘗試這樣做時,我總是收到一個 TypeScript 錯誤,告訴我加密使用的函數不是函數。

發生這種情況是因為 TypeScript 靜態分析您的文件並嘗試幫助您處理您正在使用的數據類型。 如果您使用的是用 JavaScript 編寫的函數,而沒有向 TypeScript 提供任何關於該函數用作參數的內容以及其返回值的類型的提示,則它根本無法完成其工作,這就是您收到錯誤的原因。

您可以創建一個 decalration 文件,但如果您想要快速修復並且不想在其他文件中使用這些原始 JS 函數,則不需要。 你只需要在文件中的任何地方聲明它。 您可以閱讀有關在 TypeScript 中使用declare關鍵字的更多信息

但是我仍然可以控制台記錄我導入的對象,它對我來說看起來是合法的。

從您的屏幕截圖來看,函數randomBytes被正確調用(正如您從錯誤下方打印的堆棧跟蹤中看到的那樣)。 問題是crypto對象不包含名為randomBytes的方法。 這是因為在較新的瀏覽器中, crypto是一個全局對象。

<code>crypto</code> 對象存在於瀏覽器中

您的crypto.js文件可能假設存在與瀏覽器不同的crypto全局對象。 要么在適當的范圍內提供此對象,以便您的函數可以看到它,要么使用諸如 Rollup 之類的捆綁程序內聯這些函數。

好吧,結果證明這是一個相當可怕的兔子洞。 我遵循了一堆推薦的建議,但最終對我有用的解決方案(一如既往......)超級簡單,一旦你知道如何。

答案是使用瀏覽器內置的加密功能。 我只想檢查密碼的單向摘要對於非常輕量級的應用程序是否足夠。 然而,大多數指南只是部分建議,或者不適用於我的應用程序使用 Angular 7 和 babel 的設置。 所以這是我最終得到的最終代碼,並附有以下注釋:

  • 需要編碼到數組緩沖區中以執行摘要
  • 摘要函數正在返回一個承諾,因此必須使用 .then 解開它的值
  • 不需要添加任何NPM 模塊或導入

無論如何,這是代碼,希望它可以幫助其他堆棧溢出者。

我還發現Daniel Roesler 的Github 頁面對於各種網絡密碼學示例的實現非常有用。

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-user-create',
  templateUrl: './user-create.component.html',
  styleUrls: ['./user-create.component.css']
})
export class UserCreateComponent implements OnInit {

  constructor() { }

  ngOnInit() {

    sha256("hello").then(digestValue => {
      console.log(digestValue);
    });
  }
}

async function sha256(str) {
  const encoder = new TextEncoder();
  const encdata = encoder.encode(str);
  const buf = await crypto.subtle.digest("SHA-256", encdata);
  return Array.prototype.map.call(new Uint8Array(buf), x=>(('00'+x.toString(16)).slice(-2))).join('');
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM