지돌이의 블로그 입니다!

<Axxxxx 로그인 예시>

1.     국내 유명 주요 보안 업체인 Axxxxx의 정상 로그인 테스트

 

TLS암호화 여부와 상관없이 개발자모드에서 Network Traffic을 확인해 본다.
캡처 부분 중 “SECRET_PASSWORD” 부분이 입력한 비밀번호임.

 

2.     Progress Telerik Fiddler 으로 HTTPS Decode옵션을 켜놓고 로그인 시도시
(Fidder
의 인증서는 PC에 등록하지 않음)

Fiddler 가 패킷캡쳐를 위해 MITM(중간자공격)를 수행하였고, 이를 감지하여 브라우저에서는 이를 경고한다.

 

3.     무시하고 강제 로그인시 fiddler에서 캡처

암호가 그대로 보이게 된다.

 

 

<하지만 위 상황은 안전하지 않다고 할 수 없다>

해당 연결은 TLS을 이용한 HTTPS연결을 사용하고 있다. TLS연결의 경우 비대칭 키 암호화 방식을 기반으로 한다. TLS연결의 방식을 대강 설명하자면, 서버가 가지고 있는 인증서의 Public Key을 클라이언트(브라우저)에게 보내어 클라이언트가 랜덤으로 생성한 세션 키를 서버의 Public Key로 암호화하여 서버에게 전달한다. 이 과정을 키 교환이라고 한다. 이후 과정부터는 해당 키를 통해 대칭키 암호화를 이용해 서버와 클라이언트가 보안 통신을 한다. TLS인증 방식을 무력화 하는 방법은 MITM(중간자 공격)방식이 있다. MITM방식은 중간에 Proxy서버가 자기 자신을 클라이언트에게 대상서버라고 속이는 방식이다. 그리고 서버와는 정상적인 보안 통신을 하고, 클라이언트와는 자기가 만든 가짜 인증서를 사용하여 오고가는 패킷을 볼 수 있게 된다. TLS에서는 이러한 공격을 무력화 시키기 위해 PKI(공개키 기반 구조)의 인증서를 사용한다. 이는 신뢰할 수 있는 루트 인증 기관(CA)의 인증서를 미리 컴퓨터에 저장해 놓고, CA에서 서버의 인증서의 키를 전자서명하여 인증서에 포함시킨다. 이러한 과정을 통해 MITM공격이 발생하여 서버의 인증서가 변경되면 CA의 전자서명이 없기 때문에 클라이언트 브라우저에서는 이를 인지할 수 있게 되고 따라서 사용자에게 해킹위험을 경고하여 더 이상 진행하지 않도록 한다.

 

<HSTS 적용시>

일반적인 웹 사이트의 경우 MITM공격이 발생한 경우 웹 브라우저에서 경고를 하지만 사용자 선택에 의해 해당 경고를 무시하고 다음 과정을 실행할 수 있다. 이러한 경우 사용자의 과실이지만 위 예시처럼 사용자의 크리덴셜이 노출될 수 있다.

이러한 일 또한 방지하기 위해서는 HSTS(HTTP Strict Transport Security)을 사용해야 한다. 이는 한번 이상 정상적인 방법으로 웹사이트에 접근했을 경우 브라우저가 서버 인증서를 저장하고 유지하도록 하여 이후 MITM공격이 발생하였을 때 아래 사진과 같이 더 이상 다음 과정으로 진행하지 못하게 막는 기능이다.

HSTS가 적용되어 무시하고 더이상 넘어갈 수 없다.

 

*여기서 잠깐*

만약 Fiddler으로 SSL Decrypt옵션을 켰는데 위와 같은 경고창이 뜨지 않는다면? 이는 Fiddler의 인증서를 컴퓨터에 신뢰할 수 있는 루트 인증 기관으로 저장한 것이다.

”Export root certificate to Desktop” 버튼을 누르게 되면 사용자의 컴퓨터에 Fiddler의 인증서를 신뢰할 수 있도록 저장시킨다.

 

앞서 설명했듯이 TLS PKI기반을 하며 신뢰할 수 있는 루트 인증 기관의 인증서는 미리 컴퓨터에 저장해 놓는 방식으로 서버의 인증서의 신뢰 여부를 검증한다. 하지만 만약 정상적인 CA인증서가 아닌 위와 같이 Fiddler의 인증서를 신뢰할 수 있게 하면 Fiddler가 임의로 생성한 MITM용 인증서까지 신뢰할 수 있게 된다. 따라서 브라우저도 Fiddler의 가짜 인증서를 신뢰한다고 표현하는 것이다.

실제 사용 환경에서는 해커가 사용자의 컴퓨터에 가짜 CA인증서를 저장할 수 없다. 따라서 PKI기반의 TLS통신은 안전하, 현재 TLS통신 외에 공공 네트워크에서 안전하게 통신할 수 있는 있는 방법은 세상에 존재하지 않는다.

Comment +0

Test Code:

import sun.security.pkcs11.SunPKCS11;
import sun.security.pkcs11.wrapper.PKCS11;
import sun.security.pkcs11.wrapper.PKCS11Exception;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.security.auth.login.FailedLoginException;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.UnrecoverableKeyException;

public class TestMain {
    public static void main(String[] args) throws Exception {
        TestMain app = new TestMain();
        app.run();
    }

    private boolean checkFailedLoginException(Throwable e){
        if(e instanceof FailedLoginException) {
            return true;
        }
        if(e.getCause() != null) {
            return checkFailedLoginException(e.getCause());
        }
        return false;
    }

    String dumpbin(byte[] input) {
        StringBuilder sb = new StringBuilder();
        for(byte a : input) {
            sb.append(String.format("%02x ", a & 0xff));
        }
        return sb.toString();
    }

    void run() throws Exception {
        SunPKCS11 p11Provider = new SunPKCS11("G:\\java-etoken-0.cfg");
        KeyStore keyStore = KeyStore.getInstance("PKCS11", p11Provider);
        try {
            keyStore.load(null, "P@ssw0rd".toCharArray());
        }catch (IOException loadException){
            if(checkFailedLoginException(loadException)) {
                System.err.println("LOGIN FAILED");
                return ;
            }else{
                throw loadException;
            }
        }

        Key key = keyStore.getKey("test-aes-1", null);
        System.out.println("key => " + key.getAlgorithm() + " / " + key.getFormat() + " / " + key);

        for(int i=0; i<4; i++) {
            long begin = System.nanoTime();
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", p11Provider);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            System.out.println("IV => " + dumpbin(cipher.getIV()));
            byte[] out = cipher.doFinal("0123456789abcdef0123456789abcdef".getBytes());
            System.out.println("IV => " + dumpbin(cipher.getIV()));
            long end = System.nanoTime();
            long diff = end - begin;
            System.out.println("DIFF = " + (((double) diff) / 1000000));
            System.out.println("dumpbin => " + out.length + " / " + dumpbin(out));
        }
    }
}

결과

key => AES / null / SunPKCS11-eToken AES secret key, 0 bits (id 236257286, token object, not sensitive, unextractable)
IV => 5f 89 21 65 63 56 05 2f 30 74 16 bd ed c3 53 48 
IV => 5f 89 21 65 63 56 05 2f 30 74 16 bd ed c3 53 48 
DIFF = 4196.6191
dumpbin => 32 / db e4 66 14 9f ff e8 23 8e 82 f4 0b f7 21 8a 70 f3 ef 6d a0 90 14 48 2d 7f 8b 91 9c a7 21 3f 95 
IV => 0e a3 14 ff 4c 80 94 5f 7a f0 dd b4 37 cf bc b5 
IV => 0e a3 14 ff 4c 80 94 5f 7a f0 dd b4 37 cf bc b5 
DIFF = 3.1933
dumpbin => 32 / c4 23 3c 93 8d f7 b4 8a 66 fb 8c 82 b5 27 b3 54 b4 df 8f 32 39 dc 5e 3a 93 db a4 55 5e 39 d4 f1 
IV => 40 49 64 32 f9 bd d4 43 65 eb 44 bc 9f 5d b9 c2 
IV => 40 49 64 32 f9 bd d4 43 65 eb 44 bc 9f 5d b9 c2 
DIFF = 2.836
dumpbin => 32 / ac 9c e5 68 da a4 f7 bd 4f d4 40 40 d0 c7 c0 20 90 b6 49 fb 9b 87 ac 80 3a 28 b6 75 38 8e 71 5f 
IV => c9 65 8c f3 06 80 80 5d 86 ff 85 55 44 9c 68 d6 
IV => c9 65 8c f3 06 80 80 5d 86 ff 85 55 44 9c 68 d6 
DIFF = 2.9097
dumpbin => 32 / 60 0d 1f b3 b7 db 85 1e e2 f9 99 3d 0d b2 5b 74 a5 dc 51 ba 6f fd a8 2b 9f 7f 77 75 62 7a 26 cd 

첫번째는 초기화(?) 때문에 4초란 오랜 시간이 걸리고..

동일한 Session에서는 이후 4ms 이하의 시간이 걸리는 듯 한다.

참고로 AES 256bit의 Key이다.

전에 SafeNet 5110으로 Key pair generate 테스트 할 때 시간이 오래 걸렸었는데 초기화 시간이 포함된 시간이었다.

Comment +0

https://www.npmjs.com/package/asn1-stream

 

asn1-stream

ASN1 parser with a stream interface

www.npmjs.com

asn1을 stream으로 파싱하는걸 찾았는데 없네요...

infinite length 파싱은 구현은 대충 해 놓았지만 동작하지 않을겁니다...

ASN1에 대해 잘 아시는 분은 infinite length 을 사용하는 예제 Payload좀 만들어 주세요...ㅠㅠ

아님 구현하셔서 PR주시면 매우감사!

Comment +1

  • 참고로.. 최상위 객체만 next stream으로 출력하기 때문에 최상위 객체속에 여러 객체가 있고 큰 데이터가 있으면 메모리 이슈가 발생할 수 있습니다.
    asn1으로 대용량 데이터 전송 스키마를 만드신다면 최상위 객체에 데이터를 잘라서(chunk) 길게 전달해야 합니다.

ResourceHandlerRegistry의 setOrder(0)을 줬더니 이걸 먼저 타버린다...ㅠㅠ

 

덕분에 몇시간동안 삽질을..

 

 

 

Comment +0

node.js를 runtime그대로 사용하지 않고 libnode를 이용해서 C++ Project내에 embedding하여 사용하고 있습니다.

이에 대해서는 제가 만든 node-app 소스를 이용하여 쉽게 접근할 수 있습니다.

일단 일반적인 상황에서는 테스트를 해 보았고 잘 동작하는거 같습니다만...

몇가지 Issue들이 있으며, 최근 Worker를 활용하면서 몇 가지 큰 이슈 상황이 있습니다.

(필독) 일단 기본적인 embedding에 대해

* 필수적으로 tracing관련하여 Fix된 commit을 적용해야 합니다.

#PR 31217 코멘트를 참고해 주세요. 이 PR을 모티브해서 감사하게도 #PR 31245 을 올려주셨습니다.

* NODE_USE_V8_PLATFORM=1 으로 빌드된 경우 문제되는 상황이 있습니다.

NODE_USE_V8_PLATFORM=1인 경우 libnode 내부적으로 per_process::v8_platform(export되지 않아 외부에서 사용할 수 없는 객체)을 이용하는 부분이 몇군데 있습니다. 따라서 v8_platform으로 초기화하지 않은경우 Crash가 발생하게 됩니다.

* node.js Javascript 코드 종료시 Crash 발생

제가 올린 PR #31260 에 해당 내용을 적어놓았습니다. PR은 통과되지 못하였고, 사실 좋은 방법도 아니며 Test도 통과하지 못합니다.

하지만 임시 방편으로 전 사용중입니다.

DisposePlatform() 함수를 호출하면 per_process::v8_platform.Dispose()을 하는데 v8_platform을 통해 초기화 되었는지 확인하지 않고 무조건 호출하기 때문에 v8_platform을 사용하지 못하고 직접 CreateEnvironment한 경우 Crash가 발생합니다.

threads_worker관련 Issue사항들

Embedding하여 node를 사용하면서 Worker를 사용할 때 필수적인 부분이 있습니다.

구 버전의 node인 경우 위에 v8_platform과 연관된것인데 worker의 isolate를 생성하면서 v8_platform의 Platform을 사용하는 문제가 있습니다.

따라서 6db45bf7def22eedfd95dac95713e850c366b169 커밋 이후 버전으로 빌드된 libnode.dll이 필요합니다. (PR #31217 코멘트 참고)

* Inspect초기화 문제 (Critical)

Issue #31256를 참고해 주세요.

PR #30467을 통해 해결될 수 있는데 아직 머지되지 못하였으며 코멘트들을 보면 참 많은 의견들이 있습니다..

그리고 그 사이에 또 변한 부분들이 여럿 있어서 v13 브랜치에 머지하면 현재는 다른 부분들에서 문제가 발생하기도 합니다.

저두 코드를 고쳐가며 나름 테스트를 해 보고 있습니다..

하지만 아직 Embedding환경에서 Worker사용은 시기상조인거 같습니다.

많은 분들이 관심을 가지고 nodejs측에 관심을 표현해 주심 빨리 해결되리라 생각합니다..!

참고로.. 문제가 발생하단 부분은 NodeZeroIsolateTestFixture.IsolatePlatformDelegateTest 테스트 실패인데,

(그나저나 일단 Environment Test에서 commit 1350eea23ad1da56d26bc60213734a264439aaa6 Fix가 필요하고..)

PR #30324 해당 내용 때문입니다.
PR #30467에서 FreeEnvironment할 때 DrainTasks가 추가되었는데, IsolatePlatformDelegate을 통해 Isolate를 Register했을 때 node_platform.cc의 ForNodeIsolate에서 오류가 발생합니다. shared_ptr\<PerIsolatePlatformData\>가 없기 때문에...

commit 8ab6756984c36d8b69732a71a2df5d28b03c3db5제대로된 방법일진 모르겠으나 Test는 통과합니다.

참고로 Embedding과 별개로 문제가 발생하는 경우가 있는데 PR #31215 이런 상황입니다.

그냥 제 예상으로는 worker사용시 v8 compilation cache관련하여 문제가 생기는게 아닌가 그냥 추측만 해 봅니다.

정확하게는 분석해보지 못해서 알지 못하겠구요..

암튼 코드엔 문제가 없지만 v8 engine이 잘못 해석할 수 있는 코드는 조심해야 할 것 같습니다.

저두 코드를 수정하여 해결하였습니다.

Comment +0

Error: UnsupportedEnvironment 오류

 

아마 js-crypto 라이브러리에서 오류가 날 것이다.

 

이런경우 npm install --save webcrypto-liner 를 설치하면 된다.

Comment +0

전 개발자입니다.

하마터면 rexpert한테 두손두발 다 들 뻔했지만..

그래도.. 승리 하였습니다ㅠㅠ

 

 

 

*** 근데 아래 보기전에.... 먼저.... ***

 

혹시 IE를 쓰는데 안된다면 사용하시는거가 No-add on 모드로 실행중인지 확인해 보시기 바랍니다.

그럼 안돼요...

 

https://www.thewindowsclub.com/run-internet-explorer-8-in-no-add-ons-mode

 

Run Internet Explorer in No Add-ons mode

To troubleshoot incompatible browser add-ons or extensions, run Internet Explorer in No Addons mode. The No add-ons mode in IE is rather useful.

www.thewindowsclub.com

위 화면 비슷하게 한글로 나온다면 No-add on 모드입니다.

 

바탕화면에 있는 "Internet Explorer (No add-no)" 바로가기를 복사해서 하나 더 만든다음에

우클릭 -> 속성 해서 맨 뒤에 "-extoff"를 지워주세요.

그리고 그걸로 실행하심 됩니다.

 

*** 이걸로 안된다면... ***

 

 

sen.k-teacher.or.kr 의 경우 Rexpert 1.0.0.391 버전을 사용한다고 쓰여있습니다.

다운받아서 디지털서명을 확인해 보면 무려 2010년 11월 5일에 서명된 프로그램입니다..

 

Rexpert30Viewer를 다운받아서 설치하면 C:\Program Files (x86)\clipsoft\rexpert30\bin\viewer 에 설치됩니다.

 

RexViewerCtrl30.ocx는 ActiveX기반으로 IE를 위한것으로 보이고

nprexpert3.0.plugin.dll은 Chrome을 위한 NPAPI플러그인입니다.

 

하지만.. 설치를 해도 무한 설치페이지로 이동하며 동작하지 않습니다.

Windows 7/10, IE11, Chrome 모두 그렇습니다.

 

Chrome Plugin은 NPAPI기반이라 당연히 현재 버전에서는 동작하지 않습니다.

NPAPI는 오래전에 삭제되기 시작하여 현재 버전에서는 완전히 제외되었습니다.

 

암튼... (별 시덥잖치도 않게 난독화된) Javascript도 뜯어보고 별 삽질을 다 하다가..

Chrome NPAPI를 적용하기로 해보고..

 

누군가 우리나라의 이러한 개탄스러운 상황(아래 크롬 빌드자의 발언입니다)에 안타까워 NPAPI 사용가능한 Chromed을 빌드해 올려놓으신 분이 계셔 사용해 보았습니다.

 

*STEP 0. 삭제..

IE가 켜져있으면 정상 설치가 안될 수 있으니 IE와 모든 브라우저를 닫고

C:\Program Files (x86)\clipsoft\rexpert30\bin\viewer

여기서 uninstall.rexpert30viewer.exe 을 실행해 기존버전을 삭제합니다.

 

STEP 1. NPAPI활성화된 Chromium다운로드

https://github.com/korusdipl/chromium-internal/releases

 

korusdipl/chromium-internal

Chromium self-build for Internal Use. Contribute to korusdipl/chromium-internal development by creating an account on GitHub.

github.com

 

여기서 두번째 32bit용 Chromium (42버전)을 다운받고 압축을 풉니다.

Chromium-42.0.2311.154-ia32.7z 을 받으시면 되며 7-Zip등으로 압축푸시면 됩니다.

 

STEP 2. Rexpert 설치

*절대* http://sen.k-teacher.or.kr/에서 배포하는 프로그램을 받으면 안됩니다... Chrome에서 "지원하지 않는 플러그인 입니다."라고 오류가 뜹니다.

nprexpert3.0.plugin.dll 버전이 1.0.0.1 으로 뜨는걸로 보아 개발사의 실수로 잘못 빌드되었거나 옛날 파일이 들어간거 같습니다.

 

STEP 1, 2 순서를 지켜야 합니다. STEP 2의 chrome.exe을 실행하기 전에 먼저 Rexpert를 설치해야 합니다.

 

http://tech.clipsoft.co.kr/RexServer30/cab/download/setup.jsp?version=

 

REXPERT VIEWER

REXPERT Viewer Ver: 1.0.0.0

tech.clipsoft.co.kr

위 사이트에서 받아 설치합니다.

 

 

STEP 3. Chromium을 관리자모드로 실행

 

압축 푼 폴더에서 chrome.exe를 우클릭하여 "관리자모드로 실행"합니다.

 

그리고 chrome://flags 에서 NPAPI를 활성화합니다.

위같이 나오면 "사용"을 누르시면 됩니다.

 

 

STEP 4. 해당 사이트에 접속합니다.

위 화면을 보더라도 절망하지 마시고.. (현대 버전의 크롬은 주소표시줄에서 허용을 해야 해서 그것만 주구장장 눌렀는데 안되서 전 절망할 뻔... 했지만)

 

바로 저 회색화면에서 우클릭하여 "이 플러그인 실행"을 클릭합니다.

 

STEP 5. 이제 더이상 스트레스 받지 말고 필요한 일 하시면 됩니다.

 

그리고 지금 이 상황이 화가나신다면 해당 사이트에 문의에 개선을 요망하는 글을 올려주세요...

 

아래와 같이..

 

HTML 5 표준을 지향하는 현대 인터넷 브라우져 시대에 이 무슨 시대에 뒤떨어지는 사이트와 프로그램인가요..

사이트만 번지르르하게 만들지 말고 이러한 것들도 개선해 주시기 바랍니다.

우리나라의 특성상 플러그인을 버릴 수 없다면.. 다른 정부 사이트들처럼 WebSocket을 이용한 Cross-browser프로그램이라도 개발해 주시기 바랍니다.

 

제발...

'일상' 카테고리의 다른 글

sen.k-teacher.or.kr Rexpert30Viewer 보기  (0) 2019.11.29

Comment +0

BTRFS 복구

개발 및 운영2019. 11. 22. 16:05

https://ownyourbits.com/2019/03/03/how-to-recover-a-btrfs-partition/

 

잘 설명되어있는 사이트!

 

# btrfs restore /dev/sdXY /restore/

 

마운트가 안되는 상태에서 위 명령어로 복구 가능

 

--- 아래는 번역

 

오류가 나면... 먼저 scrubing을 시도 합니다. 체크섬을 사용하여 데이터 무결성을 검사하고 손상된 데이터를 복구하려고 시도합니다. scrubing는 안전한 것으로 간주되며 일반적으로 가장 먼저 시도해야 합니다.

 

scrub 시작

# btrfs scrub start /mnt

 

scrub 상태보기

# btrfs scrub status /mnt

 

일반적으로 몇 시간이 걸립니다

이렇게 하면 가능한 한 많이 해결되지만 모든 문제를 해결하지 못할 수도 있습니다. 오류가 발생한 경우 안전을 위해 다시 복사하십시오. 아마도 우리는 많은 파일을 고쳤을 것이고 아마도 모든 파일을 고쳤을 것입니다.

 

 

... 원문을 보시길..ㅜㅜ

 

무엇보다... RAID를 쓰는 것 중요합니다. (RAID-1 이상)

그리고 RAID카드에 Backup Battrry도 꼭 다시구..

UPS는 필수입니다!

Comment +0

Kubernetes에서 사용할 Deployment/Service설정 yaml을 온라인 상에서 GUI로 만들 수 있게ㅜ도와주는걸 만들었습니다.

 

https://jc-lab.github.io/auto-generator/#/

 

kube-yaml-generator

 

jc-lab.github.io

 

github에 소스 공개되어 있으니 기능 추가 및 개선 PR주심 넘나 감사!

 

 

https://github.com/jc-lab/auto-generator/

 

jc-lab/auto-generator

Contribute to jc-lab/auto-generator development by creating an account on GitHub.

github.com

 

Comment +0

openpgp을 사용하는 프로젝트를 webpack으로 번들링하면 아래와 같은 오류가 발생한다.

Error: Cannot find module 'stream'
    at o (/bundle.js:4293:292)
    at /bundle.js:4293:449
    at Object.<anonymous> (/bundle.js:28885:38)
    at Object.76.stream (/bundle.js:28943:4)
    at o (/bundle.js:4293:398)
    at /bundle.js:4293:449
    at Object.<anonymous> (/bundle.js:28422:13)
    at Object.75../node-conversions (/bundle.js:28875:4)
    at o (/bundle.js:4293:398)
    at /bundle.js:4293:449

이런 경우 Webpack에서 openpgp패키지의 dist대신 src를 쓰게 하고

const webpack = require('webpack');
const path = require('path');

module.exports = {
    target: 'node',
    mode: 'production',
    entry: {
        main: './src/index.ts'
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
        libraryTarget: 'commonjs2'
    },
    devtool: 'source-map',
    resolve: {
        extensions: ['.ts', '.tsx', '.js'],
        alias: {
            '@src': path.resolve(__dirname, 'src')
        }
    },
    externals: {
        'crypto': 'commonjs crypto',
        'fs': 'commonjs fs',
        'stream': 'commonjs stream'
    },
    module: {
        rules: [
            // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
            { test: /\.tsx?$/, loader: "ts-loader" },

            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules\/(?!(openpgp)\/).*/,
                include: [
                    path.resolve(__dirname, "src"),
                    path.resolve(__dirname, "node_modules/openpgp")
                ],
                options: {
                    plugins: ['dynamic-import-webpack']
                }
            },
        ]
    },
    resolve: {
        modules: ['node_modules', 'src'],
        extensions: ['.js', '.json', '.jsx', '.ts'],
        alias: {
            openpgp: 'openpgp/src/index.js',
            'tweetnacl/nacl-fast-light.js': 'tweetnacl/nacl-fast.js'
        }
    },
    plugins: [
        new webpack.ContextReplacementPlugin(
            /openpgp/,
            '',
            {
                crypto: 'crypto',
                stream: 'stream',
                buffer: 'buffer',
                zlib: 'zlib',
                util: 'util'
            }
        )
    ],
    optimization: {
        minimize: false
    }
};

 

필요한 dependency들을 추가해주면 된다.

package.json의 dependencies에

    "asmcrypto.js": "github:openpgpjs/asmcrypto#6e4e407b9b8ae317925a9e677cc7b4de3e447e83",
    "elliptic": "github:openpgpjs/elliptic#6b7801573b8940a49e7b8253176ece2725841efd",
    "email-addresses": "github:openpgpjs/email-addresses#686743c6452b44bafcd06d47db7f36ddf3f3f118",

추가한다.

(주의할점은 그냥 npm install 으로 설치하면 안되고 openpgpjs의 github 리포지터리에서 가져와야 한다. 기존의 패키지를 openpgp에서 수정해서 쓰는것이기 때문)

그리고

$ npm update

$ npm install --save web-stream-tools tweetnacl text-encoding-utf-8 @mattiasbuelens/web-streams-polyfill

Comment +0