成果物
送信されたデータをサーバー側で復号しているのがわかるかと思います。
概要
今回やりたいことをスプレッドシートにまとめてみました。(画像1)
環境準備
前提としてNode.jsを使える環境を用意してください。
Node.jsが使えたらなんでも良いです。
管理人は、Dockerのubuntuのコンテナで環境を構築しました。
DockerでUbuntu環境を構築する方法は下記記事を参考にしていただけますと幸いです。
必要な物
- Node.js
- npm
- モジュールExpress
- モジュールbody-parser
- モジュールcryptico-js
ディレクトリは下記のようにしていきます。(画像2)
※rootでログインしているためsudoを省略しています。
1.homeに移動
cd home
2.ディレクトリserverを作成し、ディレクトリの移動
mkdir server
cd server
3.Node.jsのインストール
apt install nodejs
失敗したら下記コマンドを実行後、再実行(アップデート)
apt upgrade
apt-get update
4.npmのインストール
apt install npm
5.package.jsonの作成
npm init -y
6.モジュールExpressのインストール
npm install express
7.モジュールbody-parserのインストール
※これはjson形式のデータを正しく送受信するために必要です。
npm install body-parser
8.モジュールcryptico-jsのインストール
Node.jsで暗号化・復号化するためのやつ
npm i cryptico-js
9.ディレクトリhtmlの作成
mkdir html
10.ディレクトリcssの作成
mkdir css
11.ディレクトリjsの作成
mkdir js
あとは後述するコード、画像2を参考に配置してください。
コード
index.js
const express = require("express");
const cryptico =require("cryptico-js");
const app = express();
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({extended: true}))
app.use(bodyParser.json())
////////////////////公開鍵と秘密鍵の作成////////////////////
//1 キーの設定
var PassPhrase = "ansnfjansjkdnkfnasndgljkrengnasjfngajknsjkflgnajnd2323fkjngjkanskfngkljnakjsfnkjgnakjnsfgajsjoaijsidofjaojisdjfisoin2434234";
var Bits = 1024;
var MattsRSAkey = cryptico.generateRSAKey(PassPhrase, Bits);
//2 公開鍵の取り出し
var MattsPublicKeyString = cryptico.publicKeyString(MattsRSAkey);
//3 復号
var CipherText;
//////////////////////////////////////////////////////////
app.get("/", function (req, res) {
res.sendFile(__dirname + "/html/index.html");
});
app.get("/css", function (req, res) {
res.sendFile(__dirname + "/css/index.css");
});
app.get("/js", function (req, res) {
res.sendFile(__dirname + "/js/cryptico.js");
});
app.get("/key", async function (req, res) {
res.setHeader("Content-Type","application/json");
const Kdata=MattsPublicKeyString;
res.json(Kdata);
});
app.post("/send", async function (req, res) {
CipherText=req.body.cipher;
var DecryptionResult = cryptico.decrypt(CipherText, MattsRSAkey);
console.log("復号:",DecryptionResult.plaintext);
});
app.listen(8080,function() {
console.log("Listening on localhost port 3000:8080");
});
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>暗号データの送信</title>
<link rel="stylesheet" type="text/css" href="/css">
</head>
<script src="/js"></script>
<script>
//公開鍵取得
async function key() {
var key;
try {
const response = await fetch("/key", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
//公開鍵の取得
key=await response.json();
console.log("公開鍵:",key);
return key;
} catch (error) {
console.error(error);
alert("エラーが発生しました。もう一度やり直してください。");
}
}
//暗号化
function encode(MattsPublicKeyString){
let PlainText=document.getElementById('textdata').value;
if(PlainText===""){
PlainText="default";
}
var EncryptionResult = cryptico.encrypt(PlainText, MattsPublicKeyString);
console.log("暗号文:",EncryptionResult);
return EncryptionResult;
}
//暗号化データの送信
function send(){
const keydata=key();
keydata.then((result) => {
let senddata=encode(result);
const response = fetch("/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(senddata),
});
});
}
</script>
<body>
<div id="data">
<input type="text" id="textdata">
</div>
<div id="send">
<input type="button" value="送信" onclick="send()">
</div>
</body>
</html>
index.css
@charset "utf-8";
#send input{
margin-top: 30px;
margin-left: 15px;
width: 30%;
background-color: rgb(85, 80, 80);
border: 3px solid rgb(68, 221, 54);
border-radius: 30px;
color:rgb(68, 221, 54);
font-size: large;
}
#send input:active {
-webkit-transform: translate(0,2px);
-moz-transform: translate(0,2px);
transform: translate(0,2px);
}
#data input{
margin-top: 30px;
margin-left: 15px;
width: 30%;
height: 50px;
background-color: rgb(85, 80, 80);
border: 3px solid rgb(68, 221, 54);
color:rgb(68, 221, 54);
font-size: x-large;
}
body{
background-color: rgb(85, 80, 80);
}
cryptico.jsはライブラリです。
下記リンクよりソースコードをコピペして作成するか、ファイルをダウロードして配置してください。
ブラウザ側、サーバー側それぞれでcryptico.jsを使えるようにする必要があります。
そのため、Node.js側がモジュール、ブラウザ側はライブラリを使用しています。
まとめ
すごい難しいわけではありませんでしたが、地味に手間がかかりました。
Node.jsを使用していない、お試し版を記事にしております。
そちらの方が取っ付きやすいかと思いますので、本記事が難しいと感じた方は一読いただけますと幸いです。
不明点がございましたら、お気軽にコメントいただければお答えします。
ここまで読んで頂きありがとうございます。
お役に立てましたら幸いです。