웹 어플리케이션 보안 2016년 2학기 12. Cryptography.

Slides:



Advertisements
Similar presentations
순천향대학교 정보보호연구회 김현민 DES (Data Encryption Standard)
Advertisements

SSL (Secure Socket Layer) 중부대학교 정보보호학과 이병천 교수. 웹 보안 구현방법  네트워크 계층에서의 구현방법  특징  IP 계층에 보안 기능을 둠  IP Sec  응용계층의 모든 응용서비스에 보안성 제공  VPN(Virtual Private.
9 주차 실습강의 학기, 소프트웨어 설계 및 실험 ( Ⅰ ). Artificial Intelligence Laboratory Open API  API(Application Programming Interface)  응용 프로그램에서 사용할 수 있도록.
Chapter 8 현대 대칭키 암호를 이용한 암호화 기법
국내 암호이용 현황 및 암호구현 가이드 전인경
IoT(사물인터넷) 보안 2016년 2학기 4. 라즈베리파이 카메라.
Introduction to Django
MEAN Stack Front to Back (MEANAuthApp)
PHP programming 2000년 11월 13일 데이터베이스 연구실 김호숙.
10. 전자상거래 보안 e-commerce security
IT Application Development Dept. Financial Team May 24, 2005
OpenSSL 인증서 발급.
암호학 응용 Applied cryptography
Cryptography and Network Security
웹 해킹 기초와 실습.
암호화 기술(SSL, IPSec) 손재성 권기읍 안복선 최준혁
IoT(사물인터넷) 보안 2016년 2학기 3. 라즈베리파이와 node.js.
1 HTML5 개요.
12장. JSP에서 자바빈 활용 제12장.
7. JavaBeans 프로그래밍 JavaBeans JavaBeans 만들기 빈을 이용한 회원가입 양식 작성하기 빈 작성
채팅 서버 만들기 10장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03
(c) Byoungcheon Lee, Joongbu Univ.
웹어플리케이션보안 인증서 활용 중부대학교 정보보호학과 이병천 교수.
자바 암호 프로그래밍 Java Cryptography Programming
모바일 서버 만들기 13장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03
01. Index StarPlayer API Guide 01. Index 02. 상수값 정의 03. API 정의
공개키 기반구조 (Public Key Infrastructure)
제 10장 인증서 공개 키를 이용한 디지털 서명.
Chapter 3. Architecture AI & HCI Lab 김 주 영.
1장. JSP 및 Servlet을 활용한 동적 웹 프로그래밍 소개 제1장.
Chapter 8 목차 8.1 네트워크 보안이란 무엇인가? 8.2 암호학의 원리 8.3 메시지 무결성 8.4 종단점 인증
제 4장 블록 암호 모드.
Chapter 10 네트워크 보안.
암호학 응용 Applied cryptography
HTML5 입문 인공지능 연구실.
2. PHP 프로그래밍 웹 브라우저로 데이터 전송 주석 작성하기 변수/상수 문자열/숫자형 HTML 폼 만들기
HTML5 웹 프로그래밍 입문(교수용) 2장.HTML5 문서의 기본.
Chapter 3 Symmetric Key Crypto
암호학 응용 Applied cryptography
10장 SafeTalk 시스템 소프트웨어 연구실 성순화 이재일
Chapter 8 목차 8.1 네트워크 보안이란 무엇인가? 8.2 암호학의 원리 8.3 메시지 무결성 8.4 종단점 인증
JSON-RPC 서버 만들기 11장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03
Key and Certificate Management Using Keystores
DES를 이용한 GPS 위치 정보 암호화 송신 2조 김민수 문형진 안인석 조우람.
5. JSP의 내장객체1.
웹 어플리케이션 보안 2016년 2학기 8. MEAN APP – USER CRM.
MEAN Stack Front to Back (MEANAuthApp)
12 데이터베이스 사용하기.
목 차 PGP S/MIME. 전자우편 보안 Security 목 차 PGP S/MIME.
웹어플리케이션보안 forge – 자바스크립트 암호 라이브러리
Html(front end) & jsp(back end)
WebtoB Key 및 CSR생성 방법 1. 비밀키 및 CSR생성 path/ssl 에서 CSR을 생성한다.
암호학 응용 Applied cryptography
웹 어플리케이션 보안 2016년 2학기 2. Node routing.
JavaScript 기초 Chapter 8 Part II
웹어플리케이션보안 암호프로그래밍, crypto-js
인터넷응용프로그래밍 JavaScript(array).
전자상거래보안 전자우편보안 ( Security) 중부대학교 정보보호학과 이병천 교수
IoT(사물인터넷) 보안 2016년 2학기 3. 라즈베리파이와 node.js.
CGI (Common Gateway Interface)
TimeStamp를 활용한 전자문서 진본성 확보
1장. HTML5 소개 To Flash 정보영재세미나 1 김태영교수님 홍창의.
2. CONCEPTS 컴퓨터 네트워크 실험실 석사 1학기 강 동 호.
컬럼 대칭키 암호화 작업(SQL 2008) ① 마스터 키 생성 ② 인증서 생성 초기 한번만 실행 ③ 대칭키 생성
자바 암호 프로그래밍 Java Cryptography Programming
암호학 응용 Applied cryptography
Chapter 3. Public Key Infrastructure
웹어플리케이션보안 난수화 토큰인증 중부대학교 정보보호학과 이병천 교수.
Web & Internet [10] 입문 – input 태그
MEAN Stack Front to Back (MEANAuthApp)
Presentation transcript:

웹 어플리케이션 보안 2016년 2학기 12. Cryptography

12. Cryptography 자바스크립트 암호(Javascript Cryptography) 서버측 암호 (Backend Cryptography) 클라이언트측 암호 (Frontend Cryptography) 해쉬함수, 대칭키암호, 공개키암호, 전자서명, 인증서 등

Javascript Cryptography 서버측 클라이언트측

Node.js 내장 crypto 패키지 https://nodejs.org/api/crypto.html 외부 패키지 설치 필요 없이 직접 사용 가능 const crypto = require('crypto'); const secret = 'abcdefg'; const hash = crypto.createHmac('sha256', secret) .update('I love cupcakes') .digest('hex'); console.log(hash); // Prints: // c0fa1bc00531bd78ef38c628449c5102aeabd 49b5dc3a2a516ea6ea959d6658e 이것과 호환되는 브라우저측 암호 패키지는?

Node-forge https://www.npmjs.com/package/node-forge 서버측, 클라이언트측 프로그래밍을 동일한 문법으로 사용 가능 많은 암호 알고리즘, 보안 프로토콜 이용 가능

지원하는 알고리즘/프로토콜

Node-forge API 사용 방법은 온라인 API 참조 https://www.npmjs.com/package/node-forge 예: SHA-1 해쉬 함수 사용법

서버측(backend) 프로그래밍 Node-forge 패키지 설치 서버 프로그래밍에 활용 $ npm install node-forge node_modules 폴더에 node-forge 설치 서버 프로그래밍에 활용 Require를 이용하여 패키지를 불러와서 사용 var forge = require(‘node-forge’);

서버측(backend) 프로그래밍 서버 테스트용 폴더 생성 해쉬함수 프로그래밍 테스트 $ md test-server $ cd test-server 해쉬함수 프로그래밍 테스트 md.js 파일 작성 실행: $ node md.js md.js var forge = require('node-forge'); var text = 'The quick brown fox jumps over the lazy dog'; var md = forge.md.sha1.create(); md.update(text); var result = md.digest(); console.log('text: '+text); console.log('MD5: '+result.toHex());

클라이언트측(frontend) 프로그래밍 브라우저에서 사용할 forge 패키지 번들을 생성해야 함 Forge.min.js 파일 생성 필요 패키지 다운로드 https://github.com/digitalbazaar/forge 전체 다운로드 Forge.master.zip 파일 압축 풀기

클라이언트측(frontend) 프로그래밍 Package.json에 등록된 패키지 설치 $ npm install node_modules 폴더 생성

클라이언트측(frontend) 프로그래밍 브라우저에서 사용할 forge 패키지 번들 생성 $ node node_modules\requirejs\bin\r.js -o minify.js 실행 $ js/forge.min.js 파일 생성

클라이언트측(frontend) 프로그래밍 브라우저 테스트용 폴더 생성 $ md test-client, $ cd test-client forge.min.js 파일을 현재 폴더에 복사 Html 파일에서 forge.min.js 파일을 불러오면 사용 가능 <script src=“forge.min.js"></script> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Forge Test</title> <script src="forge.min.js"></script> </head> <body> <script> var text = 'The quick brown fox jumps over the lazy dog'; var md = forge.md.sha1.create(); md.update(text); var result = md.digest(); document.write('text: '+text+'<br>'); document.write('MD5: '+result.toHex()); </script> </body> </html> Index.html 똑같은 문법!!! 같은 객체 사용

Angular.js환경에서의 프로그래밍 해쉬함수 테스트

Angular.js환경에서의 프로그래밍 Index.html angular.min.js js/app.js <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Forge Hash Test</title> <!-- CSS --> <!-- load bootstrap and our stylesheet --> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> <style> body { padding-top:50px; } </style> <!-- JS --> <!-- load angular and our custom application --> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script> <script src="js/app.js"></script> <script src="js/forge.min.js"></script> </head> <!-- declare our angular application and angular controller --> <body class="container" ng-app="firstApp" ng-controller="mainController as main"> <!-- display the list using ng-repeat --> <h2>Hash Test </h2> <table class="table table-bordered"> <thead> <tr> <td>Input string</td> <td>Hash values</td> </tr> </thead> <tbody> <tr ng-repeat="computer in main.computers"> <td>{{ computer.input }}</td> <td>md5:{{ computer.md5 }} <br> sha1: {{ computer.sha1 }} <br> sha256: {{ computer.sha256 }} <br> </td> </tbody> </table> <!-- form to add computer to the list --> <form class="form-inline" ng-submit="main.addComputer()"> <input type="text" class="form-control" placeholder="Macbook" ng-model="main.computerData.input"> <button type="submit" class="btn btn-success">Add</button> </form> </body> </html> angular.min.js js/app.js js/forge.min.js 모듈, 컨트롤러를 Body에 적용 뷰 적용 항목 추가 기능

Angular.js환경에서의 프로그래밍 js/app.js 알고리즘에 따라 해쉬값을 계산하는 함수 생성 초기의 리스트 // name our angular app angular.module('firstApp', []) .controller('mainController', function() { // bind this to vm (view-model) var vm = this; vm.compHash = function(algorithm, data) { if(algorithm=='md5') var md = forge.md.md5.create(); if(algorithm=='sha1') var md = forge.md.sha1.create(); if(algorithm=='sha256') var md = forge.md.sha256.create(); md.update(data); var result = md.digest().toHex(); return result; } // define a list of items vm.computers = [ { input: 'Macbook Pro', md5: vm.compHash('md5','Macbook Pro'), sha1: vm.compHash('sha1','Macbook Pro'), sha256: vm.compHash('sha256','Macbook Pro') } ]; // information that comes from our form vm.computerData = {}; vm.addComputer = function() { // add a computer to the list vm.computers.push({ input: vm.computerData.input, md5: vm.compHash('md5', vm.computerData.input), sha1: vm.compHash('sha1', vm.computerData.input), sha256: vm.compHash('sha256', vm.computerData.input) }); // after our computer has been added, clear the form }; 알고리즘에 따라 해쉬값을 계산하는 함수 생성 초기의 리스트 항목 추가 함수

Hash and MAC

해쉬함수 해쉬함수란? 해쉬함수의 특성 해쉬함수의 용도 임의의 길이의 입력값에 대해 정해진 길이의 특징값(해쉬값)을 계산해내는 함수 입력이 같으면 해쉬값도 같음 키를 사용하지 않음 해쉬함수의 특성 일방향성 입력 메시지로부터 해쉬값을 계산하는 것은 쉬우나 해쉬값으로부터 입력 메시지를 찾아내는 것은 어려움 충돌회피성 정해진 길이의 해쉬값을 계산해내는 입력값은 여러 개가 존재하지만 충돌쌍을 실제 찾아내는 것은 계산적으로 어려움 해쉬함수의 용도 메시지가 전송중에 변조되지 않았다는 것을 검증 (Integrity)

메시지인증코드 (MAC) 메시지인증코드란? 메시지인증코드의 용도 송신자와 수신자 사이에 공유된 비밀키를 입력값으로 포함하는 해쉬 계산 입력값은 입력 메시지와 비밀키 두가지 메시지인증코드의 용도 메시지가 전송중에 변조되지 않았다는 것을 특정 수신자만이 검 증할 수 있도록 함

Hash vs. MAC 해쉬함수 메시지인증코드

해쉬함수 사례 md.js forge.md 객체를 이용 var forge = require('node-forge'); var text = 'The quick brown fox jumps over the lazy dog'; console.log('text: '+text); console.log(); var md = forge.md.sha1.create(); md.update(text); var result = md.digest(); console.log('MD5(128bit): '+result.toHex()); var md = forge.md.sha256.create(); console.log('SHA256(256bit): '+result.toHex()); var md = forge.md.sha384.create(); console.log('SHA384(384bit): '+result.toHex()); var md = forge.md.sha512.create(); console.log('SHA512(512bit): '+result.toHex()); forge.md 객체를 이용

MAC 사례 mac.js forge.hmac 객체를 이용 Key가 변경된 경우 mac 값의 차이 var forge = require('node-forge'); var text = 'The quick brown fox jumps over the lazy dog'; var key = 'super secret'; console.log('text: '+text); console.log('key: '+key); console.log(); var hmac = forge.hmac.create(); hmac.start('md5', key); hmac.update(text ); console.log('HMAC-MD5: '+hmac.digest().toHex()); hmac.start('sha1', key); console.log('HMAC-SHA1: '+hmac.digest().toHex()); hmac.start('sha256', key); console.log('HMAC-SHA256: '+hmac.digest().toHex()); forge.hmac 객체를 이용 Key가 변경된 경우 mac 값의 차이

패스워드 기반 키생성 함수 PKCS#5, Password-based cryptography PBKDF2, password-based key derivation function 2 패스워드, salt, 반복횟수 등을 기반으로 암호키를 생성하는 함수 사용자의 패스워드 입력값이 같더라도 salt , 반복횟수가 다르면 생성되는 암호키가 다름 // generate a password-based 16-byte key  // note an optional message digest can be passed as the final parameter  var salt = forge.random.getBytesSync(128); var derivedKey = forge.pkcs5.pbkdf2('password', salt, numIterations, 16);   // generate key asynchronously  // note an optional message digest can be passed before the callback  forge.pkcs5.pbkdf2('password', salt, numIterations, 16, function(err, derivedKey) {   // do something w/derivedKey  });

패스워드 기반 키생성 함수 var forge = require('node-forge'); // generate a password-based 16-byte key // note an optional message digest can be passed as the final parameter var salt = forge.random.getBytesSync(8); var password = 'super secret password'; var numIterations = 10; var derivedKey = forge.pkcs5.pbkdf2(password, salt, numIterations, 16); console.log('PBKDF2 test'); console.log('salt: '+ forge.util.bytesToHex(salt)); console.log('password: '+password); console.log('Number of iteration: '+numIterations); console.log('Derived Key(sync): '+forge.util.bytesToHex(derivedKey)); // generate key asynchronously // note an optional message digest can be passed before the callback forge.pkcs5.pbkdf2(password, salt, numIterations, 16, function(err, derivedKey) { // do something w/derivedKey console.log('Derived Key(async): '+forge.util.bytesToHex(derivedKey)); });

대칭키 암호화 대칭키 암호화 (symmetric cipher) 대칭키 암호화의 용도 송신자와 수신자가 같은 비밀키를 소유하고 암호화 통신에 사용 비밀키를 이용한 암호화 같은 비밀키를 이용한 복호화 송신자와 수신자 사이에 비밀키를 안전하게 공유(전달)해야 함 대칭키 암호화의 용도 대용량 보안통신에 활용 (통신 암호화) 정보의 암호화 저장 (DB 암호화)

Forge 에서 제공하는 대칭키 암호 암호 알고리즘: AES, DES, 3DES 암호화 운영 모드: ECB, CBC, CFB, OFB, CTR, GCM 사용 가능한 키워드 AES-ECB, AES-CBC, AES-CFB, AES-OFB, AES-CTR, AES-GCM 3DES-ECB, 3DES-CBC DES-ECB, DES-CBC

암호화 운영 모드 ECB 모드

암호화 운영 모드 CBC 모드

암호화 운영 모드 CFB 모드

암호화 운영 모드 OFB 모드

암호화 운영 모드 CTR 모드

대칭키 암호화 사례 Cipher.js forge.cipher 객체 이용 forge.random 객체를 이용한 난수 생성 // encrypt some bytes using CBC mode // (other modes include: ECB, CFB, OFB, CTR, and GCM) var cipher = forge.cipher.createCipher('AES-CBC', key); cipher.start({iv: iv}); cipher.update(forge.util.createBuffer(plaintext)); cipher.finish(); var encrypted = cipher.output;` // outputs encrypted hex console.log('Ciphertext: '+encrypted.toHex()); // decrypt some bytes using CBC mode // (other modes include: CFB, OFB, CTR, and GCM) var decipher = forge.cipher.createDecipher('AES-CBC', key); decipher.start({iv: iv}); decipher.update(encrypted); decipher.finish(); var recovered = decipher.output; // outputs decrypted hex console.log('Recovered: '+recovered.toString()); console.log(); var forge = require('node-forge'); // generate a random key and IV // Note: a key size of 16 bytes will use AES-128, 24 => AES-192, 32 => AES-256 var key = forge.random.getBytesSync(16); var iv = forge.random.getBytesSync(16); /* alternatively, generate a password-based 16-byte key var salt = forge.random.getBytesSync(128); var key = forge.pkcs5.pbkdf2('password', salt, numIterations, 16); */ var plaintext = 'Hello, world. Testing block cipher'; console.log('AES-CBC 모드 '); console.log('Plaintext: '+ plaintext); console.log('Key: '+ key); console.log('iv: '+ iv); forge.cipher 객체 이용 forge.random 객체를 이용한 난수 생성

공개키 암호화 공개키 암호화 (public key encryption) 공개키 암호화의 용도 키생성 알고리즘으로 (개인키,공개키) 쌍을 생성 사용자는 자신의 개인키를 안전하게 보관해야 하는 의무 공개키는 널리 공개 공개키 암호화의 용도 대칭키 암호화에 사용되는 비밀키를 수신자에게 안전하게 전달 속도가 느려서 대용량 통신 암호화에는 적용하지 않음

공개키 암호화 RSA 암호

전자서명 전자서명이란? 전자문서에 대한 전자적인 방법의 서명 생성 송신자가 자신의 개인키로 서명 생성 수신자가 송신자의 공개키로 서명을 검증

인증서와 전자서명인증체계(PKI) 인증서 전자서명인증체계(PKI)

Forge 에서의 RSA 활용 키생성: rsa.js Forge.pki 객체 이용 전송 및 저장 시 PEM 포맷 이용 var forge = require('node-forge'); var rsa = forge.pki.rsa; // generate an RSA key pair synchronously // *NOT RECOMMENDED* -- can be significantly slower than async var keypair = rsa.generateKeyPair({bits: 1024, e: 0x10001}); var publicKey = keypair.publicKey; var privateKey = keypair.privateKey; // pem포맷으로 변환 var pemPub = forge.pki.publicKeyToPem(publicKey); var pemPriv = forge.pki.privateKeyToPem(privateKey); console.log('Synchronous Key Generation'); console.log('Private.key: \n'+ pemPriv); console.log('Public.key: \n'+ pemPub); // generate an RSA key pair asynchronously (uses web workers if available) rsa.generateKeyPair({bits: 2048, workers: 2}, function(err, keypair) { // keypair.privateKey, keypair.publicKey }); console.log('Asynchronous Key Generation'); 키생성: rsa.js Forge.pki 객체 이용 전송 및 저장 시 PEM 포맷 이용 (openssl에서 사용하는 키, 인증서 저장 포맷)

Forge 에서의 RSA 활용 전자서명 // 키생성 되어 있다고 가정 (앞의 키생성 뒷부분에 연결하여 테스트) // sign data with a private key and output DigestInfo DER-encoded bytes // (defaults to RSASSA PKCS#1 v1.5) var message = 'Signature test with RSA-SHA1'; var md = forge.md.sha1.create(); md.update(message, 'utf8'); var signature = privateKey.sign(md); console.log('Message: '+ message); console.log('Signature: '+ forge.util.bytesToHex(signature)); // verify data with a public key var verified = publicKey.verify(md.digest().bytes(), signature); console.log('Verification: '+ verified); 전자서명

Forge 에서의 RSA 활용 RSA 암호화 // 키생성 되어 있다고 가정 (앞의 키생성 뒷부분에 연결하여 테스트) console.log('RSA encryption test'); var bytes = 'RSA encryption test sample text'; console.log('Message: '+ bytes); // encrypt data with a public key (defaults to RSAES PKCS#1 v1.5) var encrypted = publicKey.encrypt(bytes); console.log('RSA encrypted: '+ forge.util.bytesToHex(encrypted)); // decrypt data with a private key (defaults to RSAES PKCS#1 v1.5) var decrypted = privateKey.decrypt(encrypted); console.log('RSA decrypted: '+ decrypted); console.log(); console.log('RSA encryption with RSA-OAEP'); // encrypt data with a public key using RSAES-OAEP var encrypted = publicKey.encrypt(bytes, 'RSA-OAEP'); // decrypt data with a private key using RSAES-OAEP var decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP'); RSA 암호화

인증서 생성 인증서 생성: cert.js Forge.pki 객체 이용 name: 'keyUsage', keyCertSign: true, digitalSignature: true, nonRepudiation: true, keyEncipherment: true, dataEncipherment: true }, { name: 'extKeyUsage', serverAuth: true, clientAuth: true, codeSigning: true, emailProtection: true, timeStamping: true name: 'nsCertType', client: true, server: true, email: true, objsign: true, sslCA: true, emailCA: true, objCA: true name: 'subjectAltName', altNames: [{ type: 6, // URI value: 'http://cris.joongbu.ac.kr' type: 7, // IP ip: '127.0.0.1' }] name: 'subjectKeyIdentifier' }]); // self-sign certificate cert.sign(keys.privateKey); // convert a Forge certificate to PEM var pemCert = pki.certificateToPem(cert); console.log('Certificate (PEM): \n'+ pemCert); // Save certificate and privateKey to file fs.writeFileSync('certificate.cer', pemCert, 'utf8'); fs.writeFileSync('priv.pem', pemPriv, 'utf8'); var forge = require('node-forge'); var pki = forge.pki; var fs = require('fs'); // generate a keypair and create an X.509v3 certificate var keys = pki.rsa.generateKeyPair(1024); var privateKey = keys.privateKey; var publicKey = keys.publicKey; var pemPriv = forge.pki.privateKeyToPem(privateKey); var cert = pki.createCertificate(); cert.publicKey = keys.publicKey; cert.serialNumber = '01'; cert.validity.notBefore = new Date(); cert.validity.notAfter = new Date(); cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); var attrs = [{ name: 'commonName', value: 'cris.joongbu.ac.kr' }, { name: 'countryName', value: 'KR' shortName: 'ST', value: 'Sultan' name: 'localityName', value: 'Goyang' name: 'organizationName', value: 'Joongbu Univ.' shortName: 'OU', value: 'JBU' }]; cert.setSubject(attrs); cert.setIssuer(attrs); cert.setExtensions([{ name: 'basicConstraints', cA: true 인증서 생성: cert.js Forge.pki 객체 이용

인증서 생성 저장된 개인키 파일 priv.pem 저장된 인증서 파일 certificate.cer

PKCS 표준 PKCS, Public Key Cryptography Standards https://en.wikipedia.org/wiki/PKCS

PKCS#8 Private Key Information Syntax 개인키의 저장 방식 PEM 포맷 ASN.1 RSAPrivateKey PKCS#8 ASN.1 PrivateKeyInfo EncryptedPrivateKeyInfo (개인키의 패스워드 암호화 저장) Encrypted private key 공개키의 저장 인증서에 저장 PEM 포맷으로 저장 개인키로부터 공개키 추출

PKCS#8 Private Key Information Syntax var forge = require('node-forge'); var pki = forge.pki; var rsa = forge.pki.rsa; // Key Generation // generate an RSA key pair synchronously // *NOT RECOMMENDED* -- can be significantly slower than async var keypair = rsa.generateKeyPair({bits: 1024, e: 0x10001}); var publicKey = keypair.publicKey; var privateKey = keypair.privateKey; // Translate to PEM format var pemPub = forge.pki.publicKeyToPem(publicKey); var pemPriv = forge.pki.privateKeyToPem(privateKey); // PKCS#8 Test console.log('Original Public key in PEM-format'); console.log(pemPub); // convert a Forge private key to PEM-format var pemPriv = pki.privateKeyToPem(privateKey); console.log('Original Private key in PEM-format'); console.log(pemPriv); // convert a PEM-formatted private key to a Forge private key var privateKey = pki.privateKeyFromPem(pemPriv); // convert a Forge private key to an ASN.1 RSAPrivateKey var rsaPrivateKey = pki.privateKeyToAsn1(privateKey); //console.log(rsaPrivateKey); // wrap an RSAPrivateKey ASN.1 object in a PKCS#8 ASN.1 PrivateKeyInfo var privateKeyInfo = pki.wrapRsaPrivateKey(rsaPrivateKey); //console.log(privateKeyInfo); // convert a PKCS#8 ASN.1 PrivateKeyInfo to PEM var pem = pki.privateKeyInfoToPem(privateKeyInfo); console.log('ASN.1 privateKeyInfo'); console.log(pem); // encrypts a PrivateKeyInfo and outputs an EncryptedPrivateKeyInfo var encryptedPrivateKeyInfo = pki.encryptPrivateKeyInfo( privateKeyInfo, 'password', { algorithm: 'aes256', // 'aes128', 'aes192', 'aes256', '3des' }); // decrypts an ASN.1 EncryptedPrivateKeyInfo var privateKeyInfo = pki.decryptPrivateKeyInfo( encryptedPrivateKeyInfo, 'password'); // converts an EncryptedPrivateKeyInfo to PEM var pem = pki.encryptedPrivateKeyToPem(encryptedPrivateKeyInfo); console.log('Encrypted Private key: pki.encryptedPrivateKeyToPem(encryptedPrivateKeyInfo)'); console.log(pem); // converts a PEM-encoded EncryptedPrivateKeyInfo to ASN.1 format var encryptedPrivateKeyInfo = pki.encryptedPrivateKeyFromPem(pem); // wraps and encrypts a Forge private key and outputs it in PEM format var pem = pki.encryptRsaPrivateKey(privateKey, 'password'); console.log('Encrypted RSA Private key: pki.encryptRsaPrivateKey(privateKey, password) '); // decrypts a PEM-formatted, encrypted private key var privateKey = pki.decryptRsaPrivateKey(pem, 'password'); var pemPriv = pki.privateKeyToPem(privateKey); console.log('Recovered Private key from encrypted RSA private key'); console.log(pemPriv); // sets an RSA public key from a private key var publicKey = pki.setRsaPublicKey(privateKey.n, privateKey.e); var pemPub = forge.pki.publicKeyToPem(publicKey); console.log('Recovered Public key from private key '); console.log(pemPub);

PKCS#8 Private Key Information Syntax Original Public key in PEM-format -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5oy//m46f+memsVCJlGZucWmC fgFjJEaZpKG1Bf3/fV3af551ZV40BdHq135vtcVKMwEC+Xsop6abY3JnYddBMy1W C4Na2i+cjKPIyyVO4ltLfxea9HtiqxZl40eHexAQyqyzFn8RGfTYRzKR2ZSGlFRV 0R37IJ/R+ZGPZa3ALQIDAQAB -----END PUBLIC KEY----- Original Private key in PEM-format -----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQC5oy//m46f+memsVCJlGZucWmCfgFjJEaZpKG1Bf3/fV3af551 ZV40BdHq135vtcVKMwEC+Xsop6abY3JnYddBMy1WC4Na2i+cjKPIyyVO4ltLfxea 9HtiqxZl40eHexAQyqyzFn8RGfTYRzKR2ZSGlFRV0R37IJ/R+ZGPZa3ALQIDAQAB AoGBAAhoM4xH5zWniXorHZKdfeYSjMy0GCv9QJVEt24TT2V6r/1tOifm51VDzjXs fHVirgSmOq1/zuwQa6Mt5ch4zd66NdMH8LpS6gAmVr4zYfxOYIWSlkyZbHXHW1cA fci9PpO4T2o98iLdjujxP256ZkzdQB7uc0vc+DImWpVgW1OhAkEA70hw8kmjeYyc sdnWxwpqrST1SM4Vc6+kPN3ZpySirJDJqTP0nrEj5rm5SrNumWG4tz0iLVEuwEPG o5tP/fTAVwJBAMabTMueQ9QwMNE5VpOdVVdME7OJw6EiwY0s9XqEFNjoFCor7k63 FfAlK2SokB35mGzgVDHA3ktPAn2TQIgX4RsCQDpDs2zrzWiNeqI73vZ8bNlYRHnD 5KlUvXMsuhDe9NV8M/6Fbi0uCQXnd1zfMDEdAHNt6WKLgAzE9BtmeCXocOUCQQDB 2hO7K19JXUBI945pxsflzXvtYipwvVvuUFPKoeE3Vk9YWkjgzBO9sooIVf9VQqpk mxGS/o37M8NajsAOFkDBAkAAt0KqswG2Hte8oZES4htSFDhgmndi4u1BGvuub29V HdUkOSiEO+p5AJYzFw/rag31MoOwV6SU/7ROFXX8TwRt -----END RSA PRIVATE KEY----- ASN.1 privateKeyInfo -----BEGIN PRIVATE KEY----- MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALmjL/+bjp/6Z6ax UImUZm5xaYJ+AWMkRpmkobUF/f99Xdp/nnVlXjQF0erXfm+1xUozAQL5eyinpptj cmdh10EzLVYLg1raL5yMo8jLJU7iW0t/F5r0e2KrFmXjR4d7EBDKrLMWfxEZ9NhH MpHZlIaUVFXRHfsgn9H5kY9lrcAtAgMBAAECgYEACGgzjEfnNaeJeisdkp195hKM zLQYK/1AlUS3bhNPZXqv/W06J+bnVUPONex8dWKuBKY6rX/O7BBroy3lyHjN3ro1 0wfwulLqACZWvjNh/E5ghZKWTJlsdcdbVwB9yL0+k7hPaj3yIt2O6PE/bnpmTN1A Hu5zS9z4MiZalWBbU6ECQQDvSHDySaN5jJyx2dbHCmqtJPVIzhVzr6Q83dmnJKKs kMmpM/SesSPmublKs26ZYbi3PSItUS7AQ8ajm0/99MBXAkEAxptMy55D1DAw0TlW k51VV0wTs4nDoSLBjSz1eoQU2OgUKivuTrcV8CUrZKiQHfmYbOBUMcDeS08CfZNA iBfhGwJAOkOzbOvNaI16ojve9nxs2VhEecPkqVS9cyy6EN701Xwz/oVuLS4JBed3 XN8wMR0Ac23pYouADMT0G2Z4Jehw5QJBAMHaE7srX0ldQEj3jmnGx+XNe+1iKnC9 W+5QU8qh4TdWT1haSODME72yighV/1VCqmSbEZL+jfszw1qOwA4WQMECQAC3Qqqz AbYe17yhkRLiG1IUOGCad2Li7UEa+65vb1Ud1SQ5KIQ76nkAljMXD+tqDfUyg7BX pJT/tE4VdfxPBG0= -----END PRIVATE KEY----- Encrypted Private key: pki.encryptedPrivateKeyToPem(encryptedPrivateKeyInfo) -----BEGIN ENCRYPTED PRIVATE KEY----- MIICzzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIpurIMqDFQCoCAggA MB0GCWCGSAFlAwQBKgQQiZsUoexo+CHNcfJFocp+4gSCAoC6SJwVFAX7sYuPU4mD xZAa8VUxC9R4UABjBz1gs6wKEJkuYXpiCOMm7Hd9xH/KGIigHe3zCcgh2AgrAaRe pli9Xm/03pK330H9n2px2YKV9PLGB/WLLfbOAYNleOOmMnfcpCs1Fqtl35XGp/LF 9hObGMMiIYpSnWhqSrtjek5rWoKpm5hmuYI9ZKP+aiCxcuQp1bE8BoEIlclQNw7q TTj3G448+sYEzJNZbYSajSs/ggKkA5wlsAB6r0WJKMQarukGx76mY5HpSbBqphAm 4591OpUZhMu7srpsmHy4GrsbPHdhLkFamcRO4/dvo8j/uOEFozgjmfSMLrZuTp0R MPsjWos4QSFZwmfRYH59YqvlhIKjwqihGF5K5A63i8idDoGdenzhtZen8MEam6dz zZfa9shOfucjedmf5PIBH5Z9leC+8k2oLQozCbCMGTy4CMCE7mdMqeJm5YkC+BBF huSO5YTU7U3qcJI9AJUhB67Z4SYSY67a/NDALQILN9X66fJBWeeD+i5zxyC1aBGI rB0yE6slmVDPWzwpNR4vjraXr/cwaoyHJ/qD9die+CMfFzxABfVvW8Bc6dc7QFLm s3nXYjB7TGkZhSHjQVwBjjvxboC8Cbp9P8y+UtqHSclO81wGGPCdEvQ87S70urYE eYC3SKZgsv+nNILSfzavC1iFMr7f4Im2kWoPFzv1al5Eq+hDofs4AJYizUwGKpnD E47KYoS5CAyJgslfxydksf6dvihs5EMhkFE2uJ4+jv+ex1RFG3gvKYHBK+n7bInL LayLrzm1lwl4+yChKt9i7EiGMWwYYD06IBrRb6pcQjHSh1DmuGuzbcPEYvBvo5f3 AjRB -----END ENCRYPTED PRIVATE KEY----- Encrypted RSA Private key: pki.encryptRsaPrivateKey(privateKey, password) MIICzzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIuV2Z1lOf41UCAggA MB0GCWCGSAFlAwQBAgQQvdxgF4r6DE64+3lb3LUoSQSCAoAvcUl9NYaQQZ/WrdHS gLpYx1P51ZboOwBPd0++U3K5yMjmnyvVAH52GTL9MaqrCcK86SE7wAWHYiCDtWIV 7gCa2of3ojf+z10lvsn6cR3Fa3QqkO9RgwyBFxLOlpZE7uHhVkJW5LS8Pn+Pnm30 /6EAzgSJxqHLYFyh4er/Cbu+V7Ru+6KRdwpf9YjpDkHsEb20RVEJerf+Dn3F2OuB ianwIu73Dqe4+mnxH1Ycnb7cirMVaIac90W+SppMmx863n2EfD8IHd9BzO8O4rvK SjVCqkVxFL4XMKjcBh1MtE0VlEyls/HuPQt2kJJJE9PEsS3N6BZV3HddpTmDKxBw A9ChIpPmoDQexHuo1Vrtboa8Efxs3NMY5YHvObxMAvGlWCp8VfJSKvn6oupKpZpK 8ckZysvIg+EbfR4hEUFtl1ekqKt2jpIj6QQCWMaVxT79E8A9/6IU+oUG5U9QPNEC e40iiWji8fhLI7U3LOJ336cPtEZW7ZTEeyjbXJXRyqmeM8B5SqD1OwfV21s/CoRk 8SdFqOMWjfjtMEnMngO/c2LA4szzUS1/CZfrKVL0z/EstYeVphXfcyHZR8EoFuxH W3nIcshLK1+Z79LW4V8AAc467JL9eY9WBe5hVTA05RZqeCFypBpp+R9W9Tp+iG/Z R9vgMjtQWh/ElHS3DGYphwRJIp+B33lPotFVDINzATQuj9oZi8dRh7TAKt9TsP+p hWyEPbeDXTuckvqsUEaSlqqZqlju01qzatJFUG5U4c0/xsDoFKAB4k+nymzmt3qZ PdK9MYQObDykSz5io6/sDKs1JOGlpoONysy2FE46AV+SXtinbAKbD7AiesUWvt0D FZ7d

PKCS #10, 인증서 요청 양식 CSR (Certificate Signing Request) var forge = require('node-forge'); // generate a key pair var keys = forge.pki.rsa.generateKeyPair(1024); // create a certification request (CSR) var csr = forge.pki.createCertificationRequest(); csr.publicKey = keys.publicKey; csr.setSubject([{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' shortName: 'ST', value: 'Virginia' name: 'localityName', value: 'Blacksburg' name: 'organizationName', value: 'Test' shortName: 'OU', }]); // set (optional) attributes csr.setAttributes([{ name: 'challengePassword', value: 'password' }, { name: 'unstructuredName', value: 'My Company, Inc.' name: 'extensionRequest', extensions: [{ name: 'subjectAltName', altNames: [{ // 2 is DNS type type: 2, value: 'test.domain.com' value: 'other.domain.com', value: 'www.domain.net' }] }]); ; // sign certification request csr.sign(keys.privateKey); // verify certification request var verified = csr.verify(); // convert certification request to PEM-format var pem = forge.pki.certificationRequestToPem(csr); console.log('Certificate Signing Request'); console.log(pem); // convert a Forge certification request from PEM-format var csr = forge.pki.certificationRequestFromPem(pem); // get an attribute csr.getAttribute({name: 'challengePassword'}); // get extensions array csr.getAttribute({name: 'extensionRequest'}).extensions;

안전한 난수 생성 var forge = require('node-forge'); // get some random bytes synchronously var bytes = forge.random.getBytesSync(32); console.log('32-byte PRNG(sync): ',forge.util.bytesToHex(bytes)); // get some random bytes asynchronously forge.random.getBytes(32, function(err, bytes) { console.log('32-byte PRNG(async): ',forge.util.bytesToHex(bytes)); }); // generate a random prime on the main JS thread var bits = 1024; forge.prime.generateProbablePrime(bits, function(err, num) { console.log(bits,'-bit random prime(async): ', num.toString(16));

인코딩 var forge = require('node-forge'); var str = 'Test string'; console.log(str); // encode/decode base64 var encoded = forge.util.encode64(str); var str = forge.util.decode64(encoded); console.log('Base64 Encoded: ',encoded); console.log('Base64 Decoded: ',str); // encode/decode UTF-8 var encoded = forge.util.encodeUtf8(str); var str = forge.util.decodeUtf8(encoded); console.log('UTF-8 Encoded: ',encoded); console.log('UTF-8 Decoded: ',str); var bytes = forge.random.getBytesSync(16); console.log('Bytes: ',bytes); // bytes to/from hex var hex = forge.util.bytesToHex(bytes); console.log('Bytes to Hex: ',hex); var bytes = forge.util.hexToBytes(hex); console.log('Hex to Bytes: ',bytes); // parse a URL var parsed = forge.util.parseUrl('http://example.com/foo?bar=baz'); // parsed.scheme, parsed.host, parsed.port, parsed.path, parsed.fullHost console.log('URL Parsed: ',parsed);