Download presentation
Presentation is loading. Please wait.
1
웹 어플리케이션 보안 2016년 2학기 12. Cryptography
2
12. Cryptography 자바스크립트 암호(Javascript Cryptography)
서버측 암호 (Backend Cryptography) 클라이언트측 암호 (Frontend Cryptography) 해쉬함수, 대칭키암호, 공개키암호, 전자서명, 인증서 등
3
Javascript Cryptography
서버측 클라이언트측
4
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 이것과 호환되는 브라우저측 암호 패키지는?
5
Node-forge https://www.npmjs.com/package/node-forge
서버측, 클라이언트측 프로그래밍을 동일한 문법으로 사용 가능 많은 암호 알고리즘, 보안 프로토콜 이용 가능
6
지원하는 알고리즘/프로토콜
7
Node-forge API 사용 방법은 온라인 API 참조
예: SHA-1 해쉬 함수 사용법
8
서버측(backend) 프로그래밍 Node-forge 패키지 설치 서버 프로그래밍에 활용
$ npm install node-forge node_modules 폴더에 node-forge 설치 서버 프로그래밍에 활용 Require를 이용하여 패키지를 불러와서 사용 var forge = require(‘node-forge’);
9
서버측(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());
10
클라이언트측(frontend) 프로그래밍
브라우저에서 사용할 forge 패키지 번들을 생성해야 함 Forge.min.js 파일 생성 필요 패키지 다운로드 전체 다운로드 Forge.master.zip 파일 압축 풀기
11
클라이언트측(frontend) 프로그래밍
Package.json에 등록된 패키지 설치 $ npm install node_modules 폴더 생성
12
클라이언트측(frontend) 프로그래밍
브라우저에서 사용할 forge 패키지 번들 생성 $ node node_modules\requirejs\bin\r.js -o minify.js 실행 $ js/forge.min.js 파일 생성
13
클라이언트측(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 똑같은 문법!!! 같은 객체 사용
14
Angular.js환경에서의 프로그래밍 해쉬함수 테스트
15
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=" <style> body { padding-top:50px; } </style> <!-- JS --> <!-- load angular and our custom application --> <script src=" <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에 적용 뷰 적용 항목 추가 기능
16
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 }; 알고리즘에 따라 해쉬값을 계산하는 함수 생성 초기의 리스트 항목 추가 함수
17
Hash and MAC
18
해쉬함수 해쉬함수란? 해쉬함수의 특성 해쉬함수의 용도
임의의 길이의 입력값에 대해 정해진 길이의 특징값(해쉬값)을 계산해내는 함수 입력이 같으면 해쉬값도 같음 키를 사용하지 않음 해쉬함수의 특성 일방향성 입력 메시지로부터 해쉬값을 계산하는 것은 쉬우나 해쉬값으로부터 입력 메시지를 찾아내는 것은 어려움 충돌회피성 정해진 길이의 해쉬값을 계산해내는 입력값은 여러 개가 존재하지만 충돌쌍을 실제 찾아내는 것은 계산적으로 어려움 해쉬함수의 용도 메시지가 전송중에 변조되지 않았다는 것을 검증 (Integrity)
19
메시지인증코드 (MAC) 메시지인증코드란? 메시지인증코드의 용도
송신자와 수신자 사이에 공유된 비밀키를 입력값으로 포함하는 해쉬 계산 입력값은 입력 메시지와 비밀키 두가지 메시지인증코드의 용도 메시지가 전송중에 변조되지 않았다는 것을 특정 수신자만이 검 증할 수 있도록 함
20
Hash vs. MAC 해쉬함수 메시지인증코드
21
해쉬함수 사례 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 객체를 이용
22
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 값의 차이
23
패스워드 기반 키생성 함수 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 });
24
패스워드 기반 키생성 함수 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)); });
25
대칭키 암호화 대칭키 암호화 (symmetric cipher) 대칭키 암호화의 용도
송신자와 수신자가 같은 비밀키를 소유하고 암호화 통신에 사용 비밀키를 이용한 암호화 같은 비밀키를 이용한 복호화 송신자와 수신자 사이에 비밀키를 안전하게 공유(전달)해야 함 대칭키 암호화의 용도 대용량 보안통신에 활용 (통신 암호화) 정보의 암호화 저장 (DB 암호화)
26
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
27
암호화 운영 모드 ECB 모드
28
암호화 운영 모드 CBC 모드
29
암호화 운영 모드 CFB 모드
30
암호화 운영 모드 OFB 모드
31
암호화 운영 모드 CTR 모드
32
대칭키 암호화 사례 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 객체를 이용한 난수 생성
33
공개키 암호화 공개키 암호화 (public key encryption) 공개키 암호화의 용도
키생성 알고리즘으로 (개인키,공개키) 쌍을 생성 사용자는 자신의 개인키를 안전하게 보관해야 하는 의무 공개키는 널리 공개 공개키 암호화의 용도 대칭키 암호화에 사용되는 비밀키를 수신자에게 안전하게 전달 속도가 느려서 대용량 통신 암호화에는 적용하지 않음
34
공개키 암호화 RSA 암호
35
전자서명 전자서명이란? 전자문서에 대한 전자적인 방법의 서명 생성 송신자가 자신의 개인키로 서명 생성
수신자가 송신자의 공개키로 서명을 검증
36
인증서와 전자서명인증체계(PKI) 인증서 전자서명인증체계(PKI)
37
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에서 사용하는 키, 인증서 저장 포맷)
38
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); 전자서명
39
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 암호화
40
인증서 생성 인증서 생성: cert.js Forge.pki 객체 이용 name: 'keyUsage',
keyCertSign: true, digitalSignature: true, nonRepudiation: true, keyEncipherment: true, dataEncipherment: true }, { name: 'extKeyUsage', serverAuth: true, clientAuth: true, codeSigning: true, Protection: true, timeStamping: true name: 'nsCertType', client: true, server: true, true, objsign: true, sslCA: true, CA: true, objCA: true name: 'subjectAltName', altNames: [{ type: 6, // URI value: ' type: 7, // IP ip: ' ' }] 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 객체 이용
41
인증서 생성 저장된 개인키 파일 priv.pem 저장된 인증서 파일 certificate.cer
42
PKCS 표준 PKCS, Public Key Cryptography Standards
43
PKCS#8 Private Key Information Syntax
개인키의 저장 방식 PEM 포맷 ASN.1 RSAPrivateKey PKCS#8 ASN.1 PrivateKeyInfo EncryptedPrivateKeyInfo (개인키의 패스워드 암호화 저장) Encrypted private key 공개키의 저장 인증서에 저장 PEM 포맷으로 저장 개인키로부터 공개키 추출
44
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);
45
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
46
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: ' }] }]); ; // 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;
47
안전한 난수 생성 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));
48
인코딩 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(' // parsed.scheme, parsed.host, parsed.port, parsed.path, parsed.fullHost console.log('URL Parsed: ',parsed);
Similar presentations