顯示具有 數位簽章, Python 標籤的文章。 顯示所有文章
顯示具有 數位簽章, Python 標籤的文章。 顯示所有文章

2024年2月12日 星期一

Django 5.0:視圖(View)傳送串列(List)資料到模版(Template)

參考資料:Python架站特訓班Django 3最強實戰

延續專案:用擲骰子來說視圖(View)如何傳送變數到模版(Template)

範例一、依序顯示學生資料

1.設定show的URL,passdata\urls.py。

 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
"""
URL configuration for passdata project.

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from passdataapp.views import dice, dice2, dice3, show

urlpatterns = [
    path('admin/', admin.site.urls),
    path('dice/', dice),
    path('dice2/', dice2),
    path('dice3/', dice3),
    path('show/', show),
]

2.定義show()函式passdataapp\views.py。

 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
from django.shortcuts import render
import random #加入random模組

# Create your views here.
def dice(request):
    no = random.randint(1, 6) #亂數產生1-6其中一個數字
    return render(request, "dice.html", {"no":no})

def dice2(request):
    no1 = random.randint(1, 6) #亂數產生1-6其中一個數字
    no2 = random.randint(1, 6) #亂數產生1-6其中一個數字
    no3 = random.randint(1, 6) #亂數產生1-6其中一個數字
    #使用locals()函式來傳遞所有的區域變數
    return render(request, "dice2.html", locals())
    
times = 0
def dice3(request):
    global times    #宣告global變數
    times = times + 1
    local_times = times
    username = "David"
    no = random.randint(1, 6) #亂數產生1-6其中一個數字
    return render(request, "dice3.html", locals())

def show(request):
	student1 = {"name":"王老五","phone":"0928-123456", "age":20}
	student2 = {"name":"林大智","phone":"0928-123457", "age":21}
	student3 = {"name":"陳三省","phone":"0928-123458", "age":22}
	student4 = {"name":"董小于","phone":"0928-123459", "age":20}
	student5 = {"name":"曾小平","phone":"0928-123450", "age":19}
	students = [student1, student2, student3, student4, student5]
	return render(request, "show.html", locals())

3.新增templates\show.html檔案

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
<head>
	<meta charset='utf-8'>
	<title>學生基本資料</title>
</head>
<body>
	<h4>
	{% for student in students %}
		<ul>
			<li> 姓名:{{student.name}} </li>
			<li> 手機:{{student.phone}} </li>
			<li> 年紀:{{student.age}} </li>
		</ul>
	{% empty %}
		沒有任何資料
	{% endfor %}
	</h4>
</body>
</html>

執行結果:
開啟瀏覽器,輸入http://127.0.0.1:8000/show/。


範例二、利用forloop變量及其屬性由1開始顯示資料第幾位學生
4.修訂templates\show.html檔案

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
	<meta charset='utf-8'>
	<title>學生基本資料</title>
</head>
<body>
	<h6>
	{% for student in students %}
	{{forloop.counter}}位學生
		<ul>
			<li> 姓名:{{student.name}} </li>
			<li> 手機:{{student.phone}} </li>
			<li> 年紀:{{student.age}} </li>
		</ul>
	{% empty %}
		沒有任何資料
	{% endfor %}
	</h6>
</body>
</html>

執行結果:
開啟瀏覽器,輸入http://127.0.0.1:8000/show/。

範例三、for迴圈倒轉
5.修訂templates\show.html檔案

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
	<meta charset='utf-8'>
	<title>學生基本資料</title>
</head>
<body>
	<h6>
	{% for student in students reversed %}{{forloop.revcounter}}位學生
		<ul>
			<li> 姓名:{{student.name}} </li>
			<li> 手機:{{student.phone}} </li>
			<li> 年紀:{{student.age}} </li>
		</ul>
	{% empty %}
		沒有任何資料
	{% endfor %}
	</h6>
</body>
</html>

執行結果:
開啟瀏覽器,輸入http://127.0.0.1:8000/show/。


2023年12月24日 星期日

使用cryptography套件來進行數位簽章

 

程式設計說明:

利用 Python 程式碼使用 cryptography 函式庫來實現了數位簽章(Digital Signature)的功能。首先,先成金鑰對(generate_key_pair),再依照上圖來簽署訊息(sign_message)和驗證簽章(verify_signature),來實現三個函式,說明如下:

1.生成金鑰對(generate_key_pair):

  • 使用 rsa.generate_private_key 函數生成一對私鑰(private_key)和公鑰(public_key)。
  • 公鑰通常用於驗證數位簽章,私鑰用於創建數位簽章。
2.簽署訊息(sign_message):
  • 使用私鑰對給定的訊息(message)進行數位簽章。
  • 簽章過程使用了 PSS padding 和 SHA-256 hash 函數。
3.驗證簽章(verify_signature):
  • 使用公鑰對簽章進行驗證,確保簽章是由對應的私鑰創建的。
  • 如果驗證成功,返回 True,否則捕捉例外並輸出錯誤訊息,然後返回 False。

程式碼如下:

 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
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa, padding

def generate_key_pair():
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )
    public_key = private_key.public_key()
    return private_key, public_key

def sign_message(private_key, message):
    signature = private_key.sign(
        message.encode('utf-8'),
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH
        ),
        hashes.SHA256()
    )
    return signature

def verify_signature(public_key, message, signature):
    try:
        public_key.verify(
            signature,
            message.encode('utf-8'),
            padding.PSS(
                mgf=padding.MGF1(hashes.SHA256()),
                salt_length=padding.PSS.MAX_LENGTH
            ),
            hashes.SHA256()
        )
        return True
    except Exception as e:
        print(f"驗證失敗: {e}")
        return False

# Example usage:
private_key, public_key = generate_key_pair()
message_to_sign = "虎尾鎮,舊稱「大崙腳」,位於臺灣雲林縣中心,是一個因糖廠而興起的城鎮。"

signature = sign_message(private_key, message_to_sign)
print(f"數位簽章: {signature.hex()}")

if verify_signature(public_key, message_to_sign, signature):
    print("有效的數位簽章")
else:
    print("無效的數位簽章")

第一次執行結果:
數位簽章: 7006f8b687e8a0b93915822731f5bd74833a1bfc1b4bb610dbee5c6eb5ed5b99059ec9a7a6727b6dfffeb7f772079ada05f9c804abc31b13834429c1b4cc5b82719f08f6665a05211205f5f74365e0eb19f543c02139d09417fe1a7befd248face6ae8e9173d5b6a9ac5347ca0fad9fce0f5df3e7949811c786e0ff1ce389074f2e15bdf44efd46a3e420079312bad276a0322a95a538518828e9c6fa6f2cb392776ad6768524628721f311a4f7f41a8cb6019c6ff7668fe4fc96c2d64a24f43891144a96bf68e9373a26813beea80943b2a9c3bc69f966689e9c8ef93d0dfb5115b93308621b8024c9e591132fcc59cfa2dffbd6090f0f65027ab61a53e6564
有效的數位簽章

第二次執行結果:
數位簽章: 64c1c967c1f3e2866d3e4fb724e0fb74401e623be0c0f14d07ae6569edf09ca509613aa051ef5e467b6548fa6084f61fa067812832f1eabb750a1454e082cb9c03886f4e68958bdba785d3dac4a2405b3bf79e47f769c6d5b1a4dca782a280ec81337ce30b7104230058c7b61f97f2793a6b1ef63b685a59c355f05b1a9dd822094685c8445269540063120ca84356017ef3bdcf74fc4176e7704a794bb508764eb09cea3f491daac4f8adb3b958a10c279c056331147d9d0c712003bdb0a2366c487576e2916fc3fe111086c9630fbcad207a04b4f2773234248cccbbf7b191d2928fcb7db38c82f8611373b5c7843681d955a290e0784e7213ccf580bd6fae
有效的數位簽章

以上兩次執行會發現數位簽章都不同,但執行結果是一樣的,都是有效的數位簽章。

若在第47行插入下列程式:
message_to_sign = "虎尾鎮是一個因糖廠而興起的城鎮。"

修改後的程式碼如下:

 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
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa, padding

def generate_key_pair():
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )
    public_key = private_key.public_key()
    return private_key, public_key

def sign_message(private_key, message):
    signature = private_key.sign(
        message.encode('utf-8'),
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH
        ),
        hashes.SHA256()
    )
    return signature

def verify_signature(public_key, message, signature):
    try:
        public_key.verify(
            signature,
            message.encode('utf-8'),
            padding.PSS(
                mgf=padding.MGF1(hashes.SHA256()),
                salt_length=padding.PSS.MAX_LENGTH
            ),
            hashes.SHA256()
        )
        return True
    except Exception as e:
        print(f"驗證失敗: {e}")
        return False

# Example usage:
private_key, public_key = generate_key_pair()
message_to_sign = "虎尾鎮,舊稱「大崙腳」,位於臺灣雲林縣中心,是一個因糖廠而興起的城鎮。"

signature = sign_message(private_key, message_to_sign)
print(f"數位簽章: {signature.hex()}")
message_to_sign = "虎尾鎮是一個因糖廠而興起的城鎮。"
if verify_signature(public_key, message_to_sign, signature):
    print("有效的數位簽章")
else:
    print("無效的數位簽章")

執行結果:
數位簽章: 2498811122ad6bd65cfd4fcaee18c30cc75ee3007571ab8c17438cbc8b4ef1c347df20866c0e77ced3d63d19bb5a2dc87362ea76a6050429b19538ec5f416c6ea058ffc5c003e95f0aa06c15a29869190e438a72a216b226470bd5652bdc2a9949a6b51159a574eb9cfcddb77fa11617d11dcc9e55c3711088079da8bb06d80a658dc041bde272e2a1bd96a0eb80561410701aed2f22d93e68ea71a390e391093f43d9a8952005e526c174c406d9b5624298d105854282d9cf116d246075cc0b748b5f75ec7f0d860757ae16cf860c1791cef2ba3fab6a52bf6ec45c171d7cd38f5360dba55c0d23ed3e837ccc639bec923f207cc71ba9f42fbff6905fe714d7
驗證失敗: 
無效的數位簽章

以上範例告訴我們若文件內容被修改,則驗證將失敗。