2020課程設計——小組報告
課程設計項目:基于Gmssl的CA系統建構及應用
小組成員姓名學号:
20181211沈芮吉
20181212滕珠江
20181312謝繹
指導老師:婁嘉鵬
送出日期:2020年11月8日
一、設計方案及可行性分析
(一)分析選題
1.Gmssl
了解gmssl中的指令,描述支援的選項、場景和參數,制作成文檔;
在Ubuntu虛拟機下安裝gmssl,利用-help指令檢視或者使用man指令等等方式,在提示下并了解使用gmssl分工完成文檔。
2.使用OpenSSL搭建CA
頒發證書、簽名驗簽、模拟使用者和頒發機構,檢視證書等
(1)建立根CA——RootCA(自己給自己頒發證書)
生成私鑰檔案
生成自簽名證書(CA要有證書)
(2)使用者伺服器申請證書,CA伺服器頒發證書
生成私鑰
生成證書申請檔案
将申請檔案發給CA
(3)CA頒發證書--用自己的私鑰簽名
(4)證書發送用戶端
(5)在應用軟體中使用證書
3.制作網站,通過https通路
安裝Tomcat,修改Tomcat中conf檔案夾中的server.xml,注釋掉有關端口8080的代碼,加入或者修改一段端口為8443的代碼,使得https開放,修改上次制作的使用者證書裡的common name為localhost。
由于網站的證書是自建CA簽名的,浏覽器并不信任,是以需要手動導入CA憑證。
以chrome為例:設定->進階->隐私設定和安全性->管理證書
可以檢視證書詳細資訊和導入自建CA憑證
起初我們設計準備在虛拟機中進行,但是考慮到虛拟機記憶體大小,Tomcat,java代碼運作等等方面,最終選擇在主機實作。
(二)模型

1、建立CA
生成一對用于制作自簽證書的密鑰
生成自簽證書
2、用戶端(相對于CA而言的用戶端)
生成一對用于申請CA憑證密鑰
生成證書頒發請求;
将請求發給CA
3、CA端
簽署證書
将簽署完成的證書傳送給用戶端
(三)設計方案
(四)可行性分析
我們的目标是實作通過https通路,其中制作根證書、頒發證書、簽名等等十分重要,OpenSSL十分有效。
OpenSSL 是一個安全套接字層密碼庫,囊括主要的密碼算法、常用的密鑰和證書封裝管理功能及SSL協定,并提供豐富的應用程式供測試或其它目的使用。密鑰和證書管理是PKI的一個重要組成部分,OpenSSL為之提供了豐富的功能,支援多種标準。
首先,OpenSSL實作了ASN.1的證書和密鑰相關标準,提供了對證書、公鑰、私鑰、證書請求以及CRL等資料對象的DER、PEM和BASE64的編解碼功能。OpenSSL提供了産生各種公開密鑰對和對稱密鑰的方法、函數和應用程式,同時提供了對公鑰和私鑰的DER編解碼功能。并實作了私鑰的PKCS#12和PKCS#8的編解碼功能。OpenSSL在标準中提供了對私鑰的加密保護功能,使得密鑰可以安全地進行存儲和分發。
OpenSSL實作了對證書的X.509标準編解碼、PKCS#12格式的編解碼以及PKCS#7的編解碼功能。并提供了一種文本資料庫,支援證書的管理功能,包括證書密鑰産生、請求産生、證書簽發、吊銷和驗證等功能。
因而使用OpenSSL搭建CA十分有效。
二、詳細設計思路
(一)系統體系結構、技術選擇
1.證書的申請簽署步驟
2.單向認證:不需要客戶擁有CA憑證,即不需要伺服器端驗證客戶證書的過程
使用openssl指令+tomcat配置的實作過程:
3.雙向認證:需要服務端與用戶端提供身份認證
使用openssl+keytools指令+tomcat配置的實作過程:
4.最終技術選擇
基于openssl的CA系統建構
基于tomcat和自建CA的https網站部署
(二)生成CA根證書和浏覽器證書流程圖
(三)證書生成指令行解析
1.生成CA憑證,在/root目錄下建立一個ca檔案夾,并在ca檔案夾下建立四個子檔案夾
- newcerts目錄将用于存放CA簽署過的數字證書。
- private目錄用于存放CA的私鑰。
- conf目錄用于存放一些簡化參數用的配置檔案。
- server目錄存放伺服器證書檔案。
2.在conf目錄下建立一個包含如下資訊的openssl.conf檔案
su root
mkdir ca
cd ca
mkdir newcerts private conf server
cd conf/
vim openssl.conf
[ ca ]
default_ca = foo
[ foo ]
dir = /home/tzj/ca
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/private/ca.crt
serial = $dir/serial
private_key = $dir/private/ca.key
RANDFILE = $dir/private/.rand
default_days = 365
default_crl_days= 30
default_md = md5
unique_subject = no
policy = policy_any
[ policy_any ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = match
localityName = optional
commonName = supplied
emailAddress = optional
3.生成私鑰key檔案
openssl genrsa -out private/ca.key
4.執行如下指令,按照提示輸入所需資訊,然後按下Enter鍵生成證書請求csr檔案
openssl req -new -key private/ca.key -out private/ca.csr
5.執行如下指令,生成憑證crt檔案
openssl x509 -req -days 365 -in private/ca.csr -signkey private/ca.key -out private/ca.crt
6.執行如下指令,為CA的key設定起始序列号,可以是任意四個字元,建立CA鍵庫
echo 1212 > serial
touch index.txt
7.執行如下指令,為移除用戶端證書建立一個證書撤銷清單
openssl ca -gencrl -out /root/ca/private/ca.crl -crldays 7 -config "/home/tzj/ca/conf/openssl.conf"
8.為用戶端證書簽名,執行如下指令,在ca目錄内建立一個存放用戶端key的目錄users,為用戶端建立一個key
mkdir users
openssl genrsa -des3 -out /home/tzj/ca/users/client.key 1024
9.執行如下指令,為用戶端key建立一個證書簽名請求csr檔案
openssl req -new -key /home/tzj/ca/users/client.key -out /home/tzj/ca/users/client.csr
10.執行如下指令,使用CA憑證的key為用戶端key簽名
openssl ca -in /home/tzj/ca/users/client.csr -cert /home/tzj/ca/private/ca.crt -keyfile /home/tzj/ca/private/ca.key -out /home/tzj/ca/users/client.crt -config "/home/tzj/ca/conf/openssl.conf"
11.将證書轉換為PKCS12檔案
openssl pkcs12 -export -clcerts -in /home/tzj/ca/users/client.crt -inkey /home/tzj/ca/users/client.key -out /home/tzj/ca/users/client.p12
(四)列出測試目的、測試内容、測試結果,并對結果進行分析
1.測試目的:測試生成的證書是否能部署到自己制作的網站上,使得網站能用https通路
2.測試内容和測試結果:
在tomcat/conf中加入client.p12并修改conf/server.xml,增加一段代碼并注釋原來的一行代碼:
在Firefox中(工具-選項-進階-加密-檢視證書-您的證書),将private/ca.crt導入證書頒發機構
運作tomcat/bin/startup.bat,啟動tomcat
用https通路,發現可以安全通路
前面的步驟不變,在IE中導入根證書private/ca.crt
但發現顯示證書風險,此問題尚未解決
三、設計特色
(一)基于OpenSSL的CA系統建構
1.OpenSSL
OpenSSL是一個開放源代碼的軟體庫包,應用程式可以使用這個包來進行安全通信,避免竊聽,同時确認另一端連接配接者的身份。這個包廣泛被應用在網際網路的網頁伺服器上。
OpenSSL包含一個指令行工具用來完成OpenSSL庫中的所有功能。
OpenSSL是一個強大的安全套接字層密碼庫,Apache使用它加密HTTPS,OpenSSH使用它加密SSH,但是,它還是一個多用途的、跨平台的密碼工具。
OpenSSL能保證安全信道的資料保密性、資料完整性和安全驗證功能。
OpenSSL整個軟體包大概可以分成三個主要的功能部分:SSL協定庫、應用程式以及密碼算法庫。OpenSSL的目錄結構自然也是圍繞這三個功能部分進行規劃的。
作為一個基于密碼學的安全開發包,OpenSSL提供的功能相當強大和全面,囊括了主要的密碼算法、常用的密鑰和證書封裝管理功能以及SSL協定,并提供了豐富的應用程式供測試或其它目的使用。
2.CA系統
CA是證書的簽發機構,它是公鑰基礎設施(Public Key Infrastructure,PKI)的核心。CA是負責簽發證書、認證證書、管理已頒發證書的機關。
CA 擁有一個證書(内含公鑰和私鑰)。網上的公衆使用者通過驗證 CA 的簽字進而信任 CA ,任何人都可以得到 CA 的證書(含公鑰),用以驗證它所簽發的證書。
如果使用者想得到一份屬于自己的證書,他應先向 CA 提出申請。在 CA 判明申請者的身份後,便為他配置設定一個公鑰,并且 CA 将該公鑰與申請者的身份資訊綁在一起,并為之簽字後,便形成證書發給申請者。
如果一個使用者想鑒别另一個證書的真僞,他就用 CA 的公鑰對那個證書上的簽字進行驗證,一旦驗證通過,該證書就被認為是有效的。證書實際是由證書簽證機關(CA)簽發的對使用者的公鑰的認證。
證書的内容包括:電子簽證機關的資訊、公鑰使用者資訊、公鑰、權威機構的簽字和有效期等等。證書的格式和驗證方法普遍遵循X.509 國際标準。
3.OpenSSL對CA系統的支援
密鑰證書管理
密鑰和證書管理是PKI的一個重要組成部分,OpenSSL為之提供了豐富的功能,支援多種标準。
在此基礎上,OpenSSL實作了對證書的X.509标準編解碼、PKCS#12格式的編解碼以及PKCS#7的編解碼功能。并提供了一種文本資料庫,支援證書的管理功能,包括證書密鑰産生、請求産生、證書簽發、吊銷和驗證等功能。
事實上,OpenSSL提供的CA應用程式就是一個小型的證書管理中心(CA),實作了證書簽發的整個流程和證書管理的大部分機制。
SSL和TLS協定
OpenSSL實作了SSL協定的SSLv2和SSLv3,支援了其中絕大部分算法協定。OpenSSL也實作了TLSv1.0,TLS是SSLv3的标準化版,雖然差別不大,但畢竟有很多細節不盡相同。
雖然已經有衆多的軟體實作了OpenSSL的功能,但是OpenSSL裡面實作的SSL協定能夠讓我們對SSL協定有一個更加清楚的認識,因為至少存在兩點:一是OpenSSL實作的SSL協定是開放源代碼的,我們可以追究SSL協定實作的每一個細節;二是OpenSSL實作的SSL協定是純粹的SSL協定,沒有跟其它協定(如HTTP)協定結合在一起,澄清了SSL協定的本來面目。
對稱加密
非對稱加密
資訊摘要
(二)基于tomcat和自建CA的https網站部署
1.Tomcat
Tomcat是Apache 軟體基金會(Apache Software Foundation)的Jakarta 項目中的一個核心項目,由Apache、Sun 和其他一些公司及個人共同開發而成。由于有了Sun 的參與和支援,最新的Servlet 和JSP 規範總是能在Tomcat 中得到展現,Tomcat 5支援最新的Servlet 2.4 和JSP 2.0 規範。因為Tomcat 技術先進、性能穩定,而且免費,因而深受Java 愛好者的喜愛并得到了部分軟體開發商的認可,成為目前比較流行的Web 應用伺服器。
Tomcat 伺服器是一個免費的開放源代碼的Web 應用伺服器,屬于輕量級應用伺服器,在中小型系統和并發通路使用者不是很多的場合下被普遍使用,是開發和調試JSP 程式的首選。對于一個初學者來說,可以這樣認為,當在一台機器上配置好Apache 伺服器,可利用它響應HTML(标準通用标記語言下的一個應用)頁面的通路請求。實際上Tomcat是Apache 伺服器的擴充,但運作時它是獨立運作的,是以當你運作tomcat 時,它實際上作為一個與Apache 獨立的程序單獨運作的。
2.HTTPS
HTTPS(全稱:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全為目标的 HTTP 通道,在HTTP的基礎上通過傳輸加密和身份認證保證了傳輸過程的安全性。HTTPS 在HTTP 的基礎下加入SSL 層,HTTPS 的安全基礎是 SSL,是以加密的詳細内容就需要 SSL。 HTTPS 存在不同于 HTTP 的預設端口及一個加密/身份驗證層(在 HTTP與 TCP 之間)。這個系統提供了身份驗證與加密通訊方法。它被廣泛用于網際網路上安全敏感的通訊,例如交易支付等方面。HTTP 原理
① 用戶端的浏覽器首先要通過網絡與伺服器建立連接配接,該連接配接是通過TCP 來完成的,一般 TCP 連接配接的端口号是80。 建立連接配接後,客戶機發送一個請求給伺服器,請求方式的格式為:統一資源辨別符(URL)、協定版本号,後邊是 MIME 資訊包括請求修飾符、客戶機資訊和許可内容。
② 伺服器接到請求後,給予相應的響應資訊,其格式為一個狀态行,包括資訊的協定版本号、一個成功或錯誤的代碼,後邊是 MIME 資訊包括伺服器資訊、實體資訊和可能的内容。
HTTPS 原理
① 用戶端将它所支援的算法清單和一個用作産生密鑰的随機數發送給伺服器;
② 伺服器從算法清單中選擇一種加密算法,并将它和一份包含伺服器公用密鑰的證書發送給用戶端;該證書還包含了用于認證目的的伺服器辨別,伺服器同時還提供了一個用作産生密鑰的随機數;
③ 用戶端對伺服器的證書進行驗證(有關驗證證書,可以參考數字簽名),并抽取伺服器的公用密鑰;然後,再産生一個稱作 pre_master_secret 的随機密碼串,并使用伺服器的公用密鑰對其進行加密(參考非對稱加 / 解密),并将加密後的資訊發送給伺服器;
④ 用戶端與伺服器端根據 pre_master_secret 以及用戶端與伺服器的随機數值獨立計算出加密和 MAC密鑰(參考 DH密鑰交換算法);
⑤ 用戶端将所有握手消息的 MAC 值發送給伺服器;
⑥ 伺服器将所有握手消息的 MAC 值發送給用戶端。
HTTPS優點
① 使用 HTTPS 協定可認證使用者和伺服器,確定資料發送到正确的客戶機和伺服器;
② HTTPS 協定是由 SSL+HTTP 協定建構的可進行加密傳輸、身份認證的網絡協定,要比 HTTP 協定安全,可防止資料在傳輸過程中被竊取、改變,確定資料的完整性。
③ HTTPS 是現行架構下最安全的解決方案,雖然不是絕對安全,但它大幅增加了中間人攻擊的成本。
四、源代碼及注釋
(一)注冊界面核心代碼
1.通過div标簽進行分塊布局,并對每個塊進行css修飾
<div>
<h1>标題</h1>
<div class="container">主體容器,使用display: flex布局嵌套左右兩塊
<div class="w3l_form">嵌套三個文字部分内容
<h3></h3>
<h4></h4>
<p></p>
</div>
<div class="w3_info">嵌套文字說明内容和form表單
<h2></h2>
<p></p>
<form action="login.html" method="post" onsubmit="return finalCheck()">
<!--送出時進行finalcheck,具體js代碼見 2.JavaScript代碼部分
四個資訊輸入框分别用四個<div class="input-group"></div>來包含
email、password、confirm需要使用js,具體代碼見 2.JavaScript代碼部分-->
</form>
</div>
</div>
<div>頁腳</div>
</div>
2.JavaScript代碼部分
(1)送出頁面時觸發
function finalCheck() {
var user = document.getElementById("user").value;
var pw_1 = document.getElementById("pw_1").value;
var pw_2 = document.getElementById("pw_2").value;
var email = document.getElementById("email").value;
//通過document.getElementById操作擷取每一個表單域中的值,便于下面進行驗證
var passwordReg=/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6}$/; //正規表達式,形式為/^完整表達式$/ ,(?![0-9]+$)表示整個字元串不能全是數字,(?![a-zA-Z]+$) 表示整個字元串不能全是字母,[0-9A-Za-z]{6}表示整個字元串由6位數字和字母組成。
if(user != "") {//使用者名不能為空
if(pw_1 != "" && passwordReg.test(pw_1)){//密碼不為空,且符合正規表達式規定的格式
if(pw_1 == pw_2){//兩次密碼輸入一緻
alert("資訊填寫正确,可以正常送出!");
console.log("資訊填寫正确,可以正常送出!");
Store(email,pw_1);//調用Store函數進行本地存儲
return true;
returnLogin();
} else {
alert("密碼不一緻,送出失敗,請重新填寫!");
console.log("密碼不一緻,送出失敗,請重新填寫!");
return false;
}
} else {
alert("密碼格式錯誤,送出失敗,請重新填寫!");
console.log("密碼格式錯誤,送出失敗,請重新填寫!");
return false;
}
} else {
alert("注冊的賬号不符合要求,送出失敗,請重新填寫!");
console.log("注冊的賬号不符合要求,送出失敗,請重新填寫!");
return false;
}
}
function Store(email, pw_1,user) {
// 使用 localStorage 建立本地存儲的 Em/value和 Pw/value和user/value對
var storage = window.localStorage;
storage.setItem("Em", email);
storage.setItem("Pw", pw_1);
storage.setItem("user", user);
}
//在靜态界面中利用localStorage 是否建立本地存儲來判斷是否登入
var storage = window.localStorage;//擷取本地存儲
var who=storage.user;//擷取本地存儲中的user
console.log(who);//便于在控制台檢視是否存在本地存儲
function isEmpty(obj){//構造一個輔助函數來判斷obj字段是否為空或未定義,用于下面的load()函數
if(typeof obj == "undefined" || obj == null || obj == ""){
return true;
}else{
return false;
}
}
function load(){
if(!isEmpty(who)){//如果who不空,則說明是已注冊登入使用者
document.getElementById("login").innerHTML=who;
//将登入頁籤中的html内容修改為使用者名
var child=document.getElementById("register");
child.parentNode.removeChild(child); //通過擷取Id來删除靜态首頁上的注冊頁籤
}
}
(2)在對象失去焦點時觸發事件:
onblur ="checkEm(this.value) ",onblur="checkPw(this.value)",onblur="checkPwagain(this.value)"
function checkEm(Em) {
var temp = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;//正規表達式
if (Em != "" && temp.test(Em)) {
document.getElementById("remind_4").innerHTML = "郵箱格式正确";
document.getElementById("remind_4").style.color = "green";//通過js修改css樣式
} else if (Em != "" && !temp.test(Em)) {
document.getElementById("remind_4").innerHTML = "郵箱格式錯誤";
document.getElementById("remind_4").style.color = "red";
} else {
document.getElementById("remind_4").innerHTML = "郵箱不能為空";
document.getElementById("remind_4").style.color = "red";
}
}
checkPw(pw_1)與checkEm(Em)類似,正規表達式修改為/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6}$/
function checkPwagain(pw_2) {
var pw_1 = document.getElementById("pw_1").value;
if (pw_2 == "") {
document.getElementById("remind_3").innerHTML = "密碼不能為空";
document.getElementById("remind_3").style.color = "red";
} else if (pw_1 == pw_2) {
document.getElementById("remind_3").innerHTML = "兩次輸入密碼相同";
document.getElementById("remind_3").style.color = "green";
} else {
document.getElementById("remind_3").innerHTML = "兩次輸入密碼不一緻";
document.getElementById("remind_3").style.color = "red";
}
}
(二)登入界面核心代碼
<div>
<h1>标題</h1>
<div class="container">主體容器,使用display: flex布局嵌套左右兩塊
<div class="w3l_form">嵌套一個<div>包裹的<img>、三個文字部分以及一組圖檔欄内容
<div id="stage">
<img class="box x" src="../img/12.jpg" alt="" width="304" height="133">
</div>
<h3></h3>
<h4></h4>
<p></p>
<div id="imglist">
<div class="pol rotate-left float-left"><img src="../img/15.jpg" alt=""></div>
<div class="pol float-left"><img src="../img/13.jpg" alt=""></div>
<div class="pol rotate-right float-right"><img src="../img/16.jpg" alt=""></div>
</div>
</div>
<div class="w3_info">嵌套文字說明内容和form表單
<h2></h2>
<p></p>
<form action=" test.html" method="post" onsubmit="return finalCheck()">
<!--兩個資訊輸入框分别用四個<div class="input-group"></div>來包含-->
</form>
</div>
<div>頁腳</div>
</div>
2.CSS代碼部分
<style>
#stage{
perspective:100px;
margin-bottom:10px;
}/*透視效果在舞台這層表現*/
.box{
margin-top:3px;
padding:4px;/*圖檔距離邊框*/
background-color:#eee;
transition:linear 1s;/*使其具有漸進效果*/
transform-style:preserve-3d;/*3D變換的代碼*/
}
.x:hover{//滑鼠懸浮式實作3D旋轉效果
transform:rotateX(360deg);
}
.pol{
width:96px;/*每個圖檔所在的寬度*/
padding:2px;/*圖檔距離邊框*/
background-color:#eee;
border:1px solid #bfbfbf;
box-shadow:1px 1px 2px #3F9;
border-radius:5px;/*圓角邊框*/
}
.rotate-left{
transform:rotate(7deg);
}
.rotate-right{
transform:rotate(-7deg);
}
</style>
(三)靜态頁面核心代碼
1.此部分為輪播圖單獨測試
#wrapper {//主體
width: 550px;
height: 300px;
position: relative;//位置相對
margin: 300px auto;
cursor:pointer;//設定滑鼠的形狀為一隻伸出食指的手
}
#wrapper:hover .btn{//選擇滑鼠指針浮動在其上的元素
opacity: 1;//當滑鼠在上面時元素的不透明級别:完全不透明即出現
transition: all 0.6s;//指定過渡時間,産生過渡效果
}
.pic {
position: absolute;
width: 550px;
height: 300px;
opacity:0;//滑鼠不在按鈕上時完全透明即隐身
transition: all 0.8s;/指定過渡時間,産生過渡效果,時間比按鈕長,效果更佳
}
.btn {
position: absolute;
top: 135px;
background: none;
border: none;
}
.btn img{
position: absolute;
width: 50px;
height: 50px;
opacity:0.7;//滑鼠在圖檔上按鈕的效果,微微隐身
z-index: 100;//z-index 屬性設定元素的堆疊順序越高越上面
}
#btnLeft {//向左按鈕
left: 10px;
}
#btnRight {//向右按鈕
right:60px;
}
.pic.active{
z-index: 100;z-index 屬性設定元素的堆疊順序越高越上面
opacity: 1;
}
.point {
list-style: none;//把圖像設定為清單中的清單項目标記
position: absolute;
right: 20px;
bottom: 15px;
z-index: 300;//z-index 屬性設定元素的堆疊順序越高越上面
margin-bottom: 0;
}
.pot {
margin-left: 12px;
width: 8px;
height: 8px;
border: 2px solid rgba(255,255,255,0.8); //線寬,實線,顔色
float: left;
border-radius: 100%;//圓形,後面應用時方形看上去更好看就放棄了
background-color: rgba(0,0,0,0.4);
}
.pot.active {
background-color: rgba(243,149,176,1);//在該圖檔展示時即激活時的顔色
}
2.輪播圖的js檔案
let pics = document.getElementsByClassName('pic');
let btnL = document.getElementById('btnLeft');
let btnR = document.getElementById('btnRight');
let points = document.getElementsByClassName('pot');
let swiper = document.getElementById('wrapper');
//index表示第幾張圖檔在展示——>第index張圖檔有active這個類名
let index = 0;
//存儲時間
let time = null;
let clearPics = ()=> {
//全部去掉active類名
for (let i =0; i<pics.length; i++){
pics[i].className = "pic"
}
for (let i =0; i<points.length; i++){
points[i].className = "pot"
}
};
let update = ()=> {
clearPics();
//,第index張圖檔有active類名
pics[index].className = "pic active";
points[index].className = "pot active";
};
//聲明一個變量,每當執行一次btnNext函數變切換下一張圖檔并且添加active類名,當圖檔是最後一張時,下次切換回到初始圖檔
let btnNext = ()=> {
index ++;
if(index === 5){
index = 0;
}
//執行update()方法給圖檔添加active類名
update();
};
//聲明一個變量,每當執行一次btnText函數變切換上一張圖檔并且添加active類名,當圖檔是最後一張時,下次切換回到初始圖檔
let btnText = ()=> {
if (index === 0){
index = 4;
}else {
index --;
}
//執行update()方法給圖檔添加active類名
update();
};
//預設開啟定時器每一秒鐘切換下一張圖檔
time=setInterval( ()=> {
btnNext();
},1000);
//滑鼠移入圖檔關閉定時器
swiper.onmouseover = ()=> {
clearInterval(time);
};
//滑鼠移出圖檔開啟定時器,繼續執行預設操作
swiper.onmouseout = ()=> {
time=setInterval( ()=> {
btnNext();
},1000);
};
//給右鍵按鈕添加點選事件,每點選調用一次btnNext()函數
btnR.addEventListener('click', ()=> {
btnNext();
});
//給左鍵按鈕添加點選事件,每點選調用一次btnText()函數
btnL.addEventListener('click',()=> {
btnText();
});
//先周遊所有的點給一個點添加點選事件
for (let i=0; i<points.length; i++){
points[i].addEventListener('click', function() {
//聲明一個變量用來存儲目前的點是哪一位(在html裡面給标簽存入了資料)
let opt = this.getAttribute('arr');
//讓把目前點選的點值跟index相等,這樣就是保證當點選點的時候跳轉到對應的圖檔
index = opt;
update();
})
}
3.此部分為index頁中APP推薦部分滑鼠産生效果
.card-img{//APP圖檔外框設定
overflow: hidden;//超出部分隐藏
position: relative;//位置相對
}
.overlay{//淺綠色浮上來的框設定
background: rgba(78,174,58,0.5);//背景顔色不知名土棕色
position: absolute;
bottom: -100%;//使得框可以從下面浮置上方
width: 100%;//在大的塊裡足寬
height: 100%;//在大的塊裡足高
left: 50%;//左邊50%,中間位置
transform: translateX(-50%);//元素往左位移自身寬度50%的距離,整體居中
transition: all 0.3s;//産生過渡效果
}
.overlay i{//在淺綠色塊裡的十字箭頭設定
font-size: 35px;
position: absolute;
top: 50%;//上面50%,中間位置
left: 50%;//左邊50%,中間位置
//垂直居中
transform: translateX(-50%);//元素往左位移自身寬度50%的距離,整體居中
color: #4e3914;
}
.fas {
font-family: 'Font Awesome 5 Free';//Font Awesome 字型提供可縮放矢量圖示
font-weight: 900; //font-weight 屬性設定文本的粗細
}
//:before 選擇器在被選元素的内容前面插入内容
.fa-arrows-alt:before {//網頁使用Font Awesome圖示字型時,css定義 content 屬性
content: "\f0b2"; }
.fa-arrows-alt-h:before {//網頁使用Font Awesome圖示字型時,css定義 content 屬性
content: "\f337"; }
.fa-arrows-alt-v:before {//網頁使用Font Awesome圖示字型時,css定義 content 屬性
content: "\f338"; }
<div class="card-img">//圖檔分塊
<a href="https://www.iqiyi.com">
<img class="card-img-top vdpic" src="images/愛奇藝.jpg" alt="" />
<div class="overlay"><i class="fas fa-arrows-alt"></i></div>
</a>
</div>
4.此部分為movie界面裡的頁碼部分
.pagination_bar .pagination .page-item .page-link{//頁碼在大小塊裡的設定
font-size: 20px;//字寬
background: #4e3914;//背景不知名的土棕色
border: 1px solid #4e3914;//邊框不知名的土棕色
color: #ffffff;//字黑
width: 35px;
text-align: center;//文字居中
}
.pagination_bar .pagination .page-item .page-link:hover{
background: #4eae3a;//滑鼠放在頁碼的塊上時變成綠色
}
//當頁面被激活,即在該頁碼的頁面時頁碼塊變綠,字型仍為黑色
.pagination_bar .pagination .page-item .page-link.active{ background: #4eae3a;
color: #ffffff;
}
.pagination_bar_arrow .pagination .page-item .page-link{
font-size: 20px;//字寬
background: #4e3914;//背景不知名的土棕色
border: 1px solid #4e3914;//邊框不知名的土棕色
color: #ffffff;//字黑
width: 120px;
text-align: center;//文字居中
}
.pagination_bar_arrow .pagination .page-item .page-link:hover{
background: #4eae3a;
}
.sr-only {
border: 0;
clip: rect(0, 0, 0, 0);//clip 屬性剪裁絕對定位元素,方形無修剪
height: 1px;
margin: -1px;
overflow: hidden;//超出部分隐藏
padding: 0;
position: absolute;
width: 1px; }
<div class="pagination_bar">
<!-- Pagination -->
<ul class="pagination justify-content-center">
<li class="page-item">//前一頁
<a class="page-link" href="romance-page-1.html" aria-label="Previous">
//aria-label屬性用來給目前元素加上的标簽描述,接受字元串作為參數
<span aria-hidden="true">«</span>//讓這個元素對浏覽器隐藏
//«特殊符号出現在html頁面裡的一種代碼
<span class="sr-only">Previous</span>
</a>
</li>
<li class="page-item">//第一頁
<a class="page-link active" href="romance-page-1.html">1</a>
</li>
<li class="page-item">//第二頁
<a class="page-link" href="romance-page-2.html">2</a>
</li>
<li class="page-item">//第三頁
<a class="page-link" href="romance-page-3.html">3</a>
</li>
//調試過程中修改類說明和active
<li class="page-item">//後一頁
<a class="page-link" href="romance-page-2.html" aria-label="Next">
<span aria-hidden="true">»</span>
<span class="sr-only">Next</span>
</a>
</li>
</ul>
</div>
五、個人報告
(一)小組貢獻排序及依據(每個人的工作量):
謝 繹(34%):學習openssl,調試代碼指令,查閱資料,搭建CA,完成https通路,撰寫課程報告。
沈芮吉(33%):學習openssl,調試代碼指令,查閱資料,搭建CA,完成https通路,撰寫課程報告。
滕珠江(33%):學習openssl,調試代碼指令,查閱資料,搭建CA,完成https通路,撰寫課程報告。