-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhido_auth.js
173 lines (151 loc) · 7.46 KB
/
hido_auth.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
var http = require('http');
var https = require('https');
var fs = require('fs');
var express = require("express"); // npm install express
const request = require("request");
var mysql = require("mysql");
const aes256 = require('aes256');
var crypto = require('crypto');
//promise, pm2, async 사용법
var app = express();
app.use(express.json());
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; //crt의 self-signed 문제 해결
var key = fs.readFileSync('./keys/hidopr.pem', 'utf-8');
var certificate = fs.readFileSync('./keys/hido_server.crt', 'utf-8');
var credentials = { key: key, cert: certificate };
//원래는 hidoDB가 아니라 key/certification/fingerprint DB 3개로 나눠줘야함.
//우선 hidoDB내에 table3개로 구성
var connection = mysql.createConnection({//local db
host: "127.0.0.1", //localhost
user: "root",
password: "1234",
database: "hido",
port: "3306"
// multipleStatements: true // 다중쿼리용 설정(지금안됨ㅠ)
});
connection.connect();
// connection.release();
request.defaults({ //rejectUnauthorized를 false값으로 두어야 https 서버통신 가능
strictSSL: false, // allow us to use our self-signed cert for testing
rejectUnauthorized: false
});
/*========================= 지문 인증 프로세스 ======================================*/
//3. DB에 IMEI가 있는지 확인 -> 있으면 bankapp 서버에서 CI값 가져오기
app.get("/auth", function (req, res) {
//client로부터 받은 IMEI, H(sessionKey)임시로 넣어둠.
//인자 : H(Session Key), IMEI, 구동 중인 앱의 은행코드, 정보가 저장된 은행코드
var testSession = 'test';
var testIMEI = '1234';
var hash_sessionKey = (crypto.createHash('sha512').update(String(testSession)).digest('base64'));
var hash_IMEI = (crypto.createHash('sha512').update(String(testIMEI)).digest('base64'));
var curBankCode = '001';
var saveBankCode = '002';
var sql = "SELECT * FROM hido.key WHERE IMEI = ? AND bankcode = ?";
connection.query(
sql, [hash_IMEI, curBankCode], function (error, results) {
if (error) throw error;
else {
var CI = results[0].CI;
var randomNum = String(Math.floor(Math.random() * 1000) + 1);//랜덤으로 챌린지 넘버 생성
var pr = fs.readFileSync('./keys/hidopr.pem', 'utf-8');
var enChallengeNum = crypto.privateEncrypt(pr, Buffer.from(randomNum, 'utf-8')).toString('base64'); // 개인키로 암호화
var hash_enChallengeNum = (crypto.createHash('sha512').update(String(enChallengeNum)).digest('base64'));
// console.log(typeof hash_enChallengeNum);
console.log(CI, curBankCode, saveBankCode, hash_sessionKey, hash_enChallengeNum);
//4&5. DB 데이터 추가하고 challengeNum 반환
sql2 = "INSERT INTO certification (`CI`,`useBankCode`,`saveBankCode`, `sessionKey`,`challengeNum`) VALUE (?,?,?,?,?);"
connection.query(sql2, [CI, curBankCode, saveBankCode, hash_sessionKey, hash_enChallengeNum], function (error, results) {
if (error) throw error;
else {
console.log("db certification에 데이터 넣었음");
var jsonData = { "challengeNum": hash_enChallengeNum };
res.send(jsonData);
}
});
}
});
});
//6&8.fido서버에 CI 보내고 publicKeyB 요청 + 11.사용자 검증
request('https://127.0.0.1:3001/auth', function (error, response, body) {
//console.error('error:', error);
//console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
if (!error && response.statusCode == 200) {
var data = JSON.parse(body);
console.log(data);
//이미 다 hash된 값이 넘어옴.
var CI = data.CI;
var publicKeyB = data.publicKeyB;
if (publicKeyB != null) {//publickeyB를 certDB에 저장(인증후 삭제)
var sql = "UPDATE key SET publicKeyB = ? WHERE CI = ?";
connection.query(sql, [publicKeyB, CI], function (error, results) {
if (error) throw error;
else {
console.log("update key table");
}
})
} else {
console.log("CI 없음");
}
}
//Q.certificationDB에서 useBankCode, sessionKey 검색해서 CI획득<이미 CI값이 넘어오는데?
var useBankCode = '001';
if (CI != null) {//KeyDB에서 CI,useBankCode로 KeyA 획득
var sql = "SELECT * FROM key WHERE CI = ? AND useBankCode = ?";
connection.query(sql, [CI, useBankCode], function (error, results) {
if (error) throw error;
else {
var publicKeyA = results[0].publicKeyA;
var publicKey = publicKeyA + publicKeyB//KeyA+keyB로 완벽한 publicKey 획득
console.log(publicKey);
}
})
} else {
console.log("CI 없음");
}
/*챌린지넘버 복호화 후, 해시시켜서 certDB에 저장된 챌린지넘버와 비교
HIDO 서버가 bankapp서버에 인증 결과 전송 */
var pu = fs.readFileSync('./keys/pu.pem', 'utf-8');
var enChallengeNum = fs.readFileSync('./keys/test.txt', 'utf-8');//클라이언트에서 넘어오는 hash된 챌린지넘버(임의로 지정)
var deChallengeNum = crypto.publicDecrypt(pu, Buffer.from(enChallengeNum, 'base64')); // 공개키로 복호화
console.log("deChallengeNum : " + deChallengeNum.toString() + "\n");
var hashChallengeNum = (crypto.createHash('sha512').update(String(deChallengeNum)).digest('base64')); //해시
console.log(hashChallengeNum);
var sql = "SELECT * FROM certification WHERE CI = ?";
connection.query(sql, [CI], function (error, results) {
if (error) throw error;
else {
var sessionKey = results[0].sessionKey;
var useBankCode = results[0].useBankCode;
var hash_IMEI = results[0].hash_IMEI;
var saveBankCode = results[0].saveBankCode;
var challengeNum = results[0].challengeNum;
if (hashChallengeNum == challengeNum) {
console.log("AUTHENTICATION & TRANSFER: " + "Session Key [" + sessionKey + "] Use App Code [" + useBankCode
+ "] IMEI [" + hash_IMEI + "] Saved Bank code [" + saveBankCode + "] Challenge number [" + challengeNum + "]");
sql2 = "UPDATE key SET publicKeyB = ? WHERE CI = ?"
connection.query(sql2, [" ", CI], function (error, results) {
if (error) throw error;
else {
console.log("publicKeyB destoryed");
}
});
var output = {
"mode": "auth",
"result": "true"
}
res.send(output);
} else {
console.log("AUTHENTICATION - FAIL");
var output={
"mode":"logout",
"result":"false"
}
res.send(output);
}
}
})
});
var httpsServer = https.createServer(credentials, app);
httpsServer.listen(3002);
console.log('Server running');