【Python】RC4の実装

def KSA(key):
	S = list(range(256))
	j = 0
	for i in range(256):
		j = (j + S[i] + ord(key[i % len(key)])) % 256
		S[i], S[j] = S[j], S[i]
	return S

def PRGA(S):
	i,j = 0, 0
	while True:
		i = (i + 1) % 256
		j = (j + S[i]) % 256
		S[i], S[j] = S[j], S[i]
		K = S[(S[i] + S[j]) % 256]
		yield K

def RC4(data, key):
	S = KSA(key)
	gen = PRGA(S)
	data = bytearray(data, encoding='utf-8')
	result = bytearray(c ^ n for c, n in zip(data, gen))
	return str(result)

key = 'this_is_a_key'
message = 'this_is_a_message'

chiphertext = RC4(message, key)
print(chiphertext)

これでもいける

from Crypto.Cipher import ARC4
key = b'Very long and confidential key'
cipher = ARC4.new(key)
msg = cipher.encrypt(b'Open the pod bay doors, HAL')
print(msg)

【Python】DESを実装する

$ pip3 install base32hex

import base32hex
import hashlib
from Crypto.Cipher import DES
from Crypto.Random import get_random_bytes

password = "Password"
salt = '\x28\xAB\xBC\xCD\xDE\xEF\x00\x33'
key = password + salt
m = hashlib.md5(key)
key = m.digest()
(dk, iv) = (key[:8], key[8:])
crypter = DES.new(dk, DES.MODE_CBC, iv)

plain_text = "hello world"

print("The plain text is:", plain_text)
plain_text += '\x00' * (8 - len(plainn_text) % 8)
ciphertext = crypter.encrypt(plain_text)
encode_string = base32hex.b32encode(ciphertext)
print("the encoded string is : ", encode_string)

Traceback (most recent call last):
File “aes.py”, line 9, in
m = hashlib.md5(key)
TypeError: Unicode-objects must be encoded before hashing

pyDesを使用します。
$ pip3 install pyDes
https://github.com/twhiteman/pyDes

from pyDes import *

data = "Please encrypt my data"
k = des("DESCRYPT", CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5)
d = k.encrypt(data)
print(d)
print(k.decrypt(d))

b’o\xceSef\xe6\xa6\x8f\x82\x98\xc7V\xd0I\xdc\x03\x1e\x97\xe4\x99&\x07\x9cI’
b’Please encrypt my data’

【Python】AESを実装しよう

pycryptodomeをインストールします
$ pip3 install pycryptodome

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util import Padding
from hashlib import pbkdf2_hmac

targetText = "hello world"

salt = get_random_bytes(16)
iv = get_random_bytes(16)

passPhrase = "password123"

key = pbkdf2_hmac('sha256', bytes(passPhrase, encoding='utf-8'), salt, 50000, int(128/8))

aes = AES.new(key, AES.MODE_CBC, iv)
data = Padding.pad(targetText.encode('utf-8'), AES.block_size, 'pkcs7')
encrypted = aes.encrypt(data)
print(encrypted)

$ python3 aes.py
b’\x86\xb4V\x7f\xfaN\x83\xc9\x87\x02\xd1\x15z\x19bU’

flaskでcssを使いたい

cssファイルはtemplatesフォルダ配下には作らない
↓これはダメ
$ tree
.
├── app.py
└── templates
├── css
│   └── style.css
└── index.html

staticというフォルダを作り、その中にcssファイルを入れる
$ tree
.
├── app.py
├── static
│   └── style.css
└── templates
└── index.html

templateからは以下で読み込む

	<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" type="text/css">

flask JSONを返却する

jsonifyを使用する

from flask import Flask, render_template, request, jsonify

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
app.config['JSON_SORT_KEYS'] = False

@app.route('/hello')
def hello():
	data = [
		{"name": "山田"},
		{"age": 30}
	]
	return jsonify({
			'status' : 'OK',
			'data' : data
		})

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

flask formからPOST

formを受け取る側はmethodsを指定する必要あり

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/form')
def form(name=None):
	return render_template('post.html')

@app.route('/hello', methods=["POST"])
def hello():
	if request.method == 'POST':
		name = request.form['name']
	else:
		name = 'no name.'

	return render_template('hello.html', title='flask test', name=name)

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

queryをgetで取得する場合
=> request.args.getで取得する
http://192.168.56.10:8000/hello?name=yoko

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/hello')
def hello():
	name = request.args.get('name')

	return render_template('hello.html', title='flask test', name=name)

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

flask パラメータとルーティング

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/hello/<name>')
def hello(name=None):

	return render_template('hello.html', title='flask test', name=name)

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

flask データベース利用

MySQLにデータが入っています
mysql> select * from users;
+——–+———————-+
| number | name |
+——–+———————-+
| 2 | Achraf Hakimi |
| 4 | Manuel Ugarte |
| 5 | Marquinhos |
| 7 | Kylian Mbappé |
| 8 | Fabián Ruiz |
| 10 | Neymar |
| 11 | Marco Asensio |
| 14 | Juan Bernat |
| 18 | Renato Sanches |
| 99 | Gianluigi Donnarumma |
+——–+———————-+
10 rows in set (0.00 sec)

$ pip3 install PyMySQL

hello.py

from flask import Flask, render_template
import pymysql

app = Flask(__name__)

@app.route('/')
def hello():

	db = pymysql.connect(
			host='localhost',
			user='hoge',
			password='fuga',
			db='test',
			charset='utf8',
			cursorclass=pymysql.cursors.DictCursor,
		)
	cur = db.cursor()
	sql = "select * from users"
	cur.execute(sql)
	users = cur.fetchall()

	cur.close()
	db.close()

	return render_template('hello.html', title='flask test', users=users)

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

templates/hello.html

{% extends "layout.html" %}
{% block content %}
<h3>一覧</h3>
<ul>
{% for user in users %}
	<li>{{ user.number }} : {{ user.name }}</li>
{% endfor %}
</ul>
{% endblock %}

flask テンプレートの利用

templates/layout.html

<!doctype html>
<html>
<head>
	<title>{{ title }}</title>
</head>
<body>
	{% block content %}
	{% endblock %}
</body>
</html>

templates/hello.html

{% extends "layout.html" %}
{% block content %}
<h3></h3>
こんにちは。{{ name }}さん。
{% endblock %}

hello.py

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def hello():
	name = "Hoge"
	return render_template('hello.html', title='flask test', name=name)

if __name__ == "__main__":
	app.run(debug=True, host='192.168.56.10', port=8000)

【Blockchain】トランザクションへの電子署名の実装

import pandas as pd
import datetime
from ecdsa import SigningKey, SECP256k1
import binascii
import json

secret_key_A_str = "47c5c280197c691be3f80462b72d60b7b2915753f1a81a6eedbfbb2f01f55cae"
public_key_B_str = "02cfbf50fe5873ac6e5352e7524c4934e32f01281fc7d6112fed86cf58e72b09bb302f1f7d10d7c37d13eb7e62fd8bb1950b263c51ac76581f8b0a38d0d8853e"

secret_key_A = SigningKey.from_string(binascii.unhexlify(secret_key_A_str), curve=SECP256k1)
public_key_A = secret_key_A.verifying_key
public_key_A_str = public_key_A.to_string().hex()
time_now = datetime.datetime.now(datetime.timezone.utc).isoformat()

unsigned_transaction = {"time": time_now, "sender": public_key_A_str, "receiver": public_key_B_str, "amount": 3}
signature = secret_key_A.sign(json.dumps(unsigned_transaction).encode('utf-8'))
transaction = {"time": time_now, "sender": public_key_A_str, "receiver": public_key_B_str, "amount": 3, "signature": signature.hex()}

pd.to_pickle(transaction, "signed_transaction.pkl")

取引記録の検証

import pandas as pd
from ecdsa import VerifyingKey, BadSignatureError, SECP256k1
import binascii
import json

transaction = pd.read_pickle("signed_transaction.pkl")
public_key_A = VerifyingKey.from_string(binascii.unhexlify(transaction["sender"]), curve=SECP256k1)
signature = binascii.unhexlify(transaction["signature"])

unsigned_transaction = {
	"time": transaction["time"],
	"sender": transaction["sender"],
	"receiver": transaction["receiver"],
	"amount": transaction["amount"]
}

try:
	public_key_A.verify(signature, json.dumps(unsigned_transaction).encode('utf-8'))
	print("トランザクションは改竄されていません。")
except BadSignatureError:
	print("トランザクションは改竄されています。")

$ python3 verify_transaction.py
トランザクションは改竄されていません。

cheat.py

import pandas as pd

transaction = pd.read_pickle("signed_transaction.pkl")
print("改竄前のトランザクション:")
print(transaction)

transaction = {"time": transaction["time"], "sender": transaction["sender"], "receiver": transaction["receiver"], "amount": 30, "signature": transaction["signature"]}
print("改竄後のトランザクション:")
print(transaction)
pd.to_pickle(transaction, "signed_transaction.pkl")

改竄するとsignatureが変更されていないので、改竄されていることがわかる