---
# System prepended metadata

title: 投票專題 111下學期

---

# 投票專題 111下學期

[投票專題 Overview](https://hackmd.io/@zRWCfXc1TOaCsnINOAPeCw/HkkDB4G12)
[投票專題 111上學期](https://hackmd.io/@zRWCfXc1TOaCsnINOAPeCw/not6914)
[投票專題 112上學期](https://hackmd.io/@zRWCfXc1TOaCsnINOAPeCw/Hkv1faxuh)
[系統整合實作的 Github organization](https://github.com/System-Integration-Implementation)

---

# 0127 Update

要問的問題
1. 太過口語大概要怎麼改才可以避免? chatGPT可能可以潤稿
2. 那幾個安全性我們要怎麼挑(要寫幾項)? FIDO可以考慮寫深一點(就變成其他的殺掉)
3. 參考資料的格式要怎麼做? 看國科會有沒有規定的引註格式；若無則到google scholar；計畫中citation不是重點，就大概寫一下，不要寫錯就好。使用編號的格式，跟通識報告不一樣。
![](https://i.imgur.com/eGqQh8T.png =80%x)

## 建議

錯字

文獻回顧與技術偏向口語
文獻回顧:
提每個技術之前，要先敘述一下為什麼樣用這個技術、想解決甚麼問題
參考wiki、論文看要怎麼科普給讀者讀懂，對技術需一定熟悉度，說明起來別人比較容易聽懂

以FIDO為舉例:
密碼比對被猜中或偷走時，就會相當不安全；因此無密碼會相較安全
公私鑰身分認證那邊要回去聽錄影檔
"安全晶片"那邊也是聽錄影檔

因此需要多找一些資料

時序上整理(對投票流程): 哪個投票流程對應哪個技術
講安全的時候，可以根據CIA來分類(甚麼技術注重在CIA的哪一項)

定義性質，並說明這個性質怎麼樣算是達成。

安全性設定為稍微敏感一點的場合，公職選舉需考慮的事情太多

安全晶片: 正確認證身分、資料不被改
其他的技術主要在匿名性(可以考慮不要放了，因為只寫兩個就足夠了)

資格、可驗證性

**小結**: 面向、流程可以再修正優化；問題可以定義得更清楚

**可以使用chatGPT** [連結](https://openai.com/blog/chatgpt/)
[APA](https://www.citationmachine.net/apa)
[論文大小事](http://nan.logdown.com/post/2013/08/27/academic-writing-referencing-and-citation)

## 暫時不需要放到計劃書的東西
Re-encryption Mix-net
    這個技術可以對一組密文執行重新加密，並打亂這些密文的順序，每個混合服務器接收一組消息，並以秘密的隨機順序將它們轉發到下一個混合服務器。通過重新加密，mix-net（或shuffle agent）不需要解密密文，而是使用許可權公鑰並將密文轉換為另一個數字，其中解密此密文保持不變。傳遞shuffle agent的過程，原始順序密文將不為人知，因此作者將無法追蹤密文的獨創性。在電子投票中，mix-net通常用於在投票提交或解密過程中提供匿名性。

盲簽名結合區塊鏈系統
（會有灌票疑慮）

同態加密( homomorphic encryption)
    同態加密，就是說，對明文A加密後的密文A做代數的運算後，所得出來的結果(密文B)，將過解密，所得到的明文B和對明文A做同樣的代數運算後，所得的結果是相同的。在電子投票系統中，可以應用在驗票環節。驗票、計算結果時，選票將維持在加密的狀態下，計票。計算過程中可確保不被第三方得知內容，達到保護投票者的效果。




================註解================
// 補一段關於身分認證的概論
//參考論文的(Fido.pdf)p.14
//option
我們主要參考〈基於 Fido 身份識別協定之行動應用 使用者驗證機制設計〉這篇論文來實作FIDO機制。
FIDO
// 把FIDO介紹一次
// 從FIDO1.0的U2F, UAF到FIDO2
// 有三大原則，易用性(Ease of use)、隱私安全(Privacy and security)以及標準化(Standardaization)
// FIDO1.0由U2F與UAF組成
// 參考資料: 論文
// 流程: FIDO介紹->UAF->U2F->FIDO2.0
(->解決機密性/安全性)
//U2F，我額外又參考了(https://fidoalliance.org/specs/u2f-specs-master/fido-u2f-overview.html)
中的Site-Specific Public/Private Key Pairs段落

安全晶片
// 參考資料: google pixel3的那兩篇網站
(https://www.howtogeek.com/387934/your-smartphone-has-a-special-security-chip.-heres-how-it-works/#comments)
(https://www.blog.google/products/pixel/titan-m-makes-pixel-3-our-most-secure-phone-yet/)
================註解================


與 安全晶片

FIDO是身分認證的標準，由FIDO聯盟所定出。因為有近80%的資料外洩，原因和密碼有關，所以FIDO以公開金鑰加密、多因子認證(不僅僅是使用密碼，還使用其他方式做驗證)、生物辨識特性，以使用者裝置進行認證。並且把這些認證資訊存在使用者端的硬體上。
	
	
在電子投票中，可以做為驗證的使用裝置的是否是該裝置的所有者，可以避免冒名投票。並且因為認證的資訊都儲存在使用者的裝置中，所以不會有投票系統管理者權限過大的問題。
	
安全晶片，則可以可作為「FIDO 密碼核心」，支援 FIDO 密碼演算法、認證機制等，兼容指紋認證模組(生物辨識)、USB安全金鑰、身分認證卡等。


## 下周進度

---

# 0205 Update
不含參考資料要10頁
參考資料真的沒有規定格式 所以就是APA
## 可以問的問題
1. challenge/response要多寫上去嗎?因為有提到
不用完整寫
2. 安全晶片有多的資料嗎?
電子錢包之類的 用安全晶片做了哪些事情 -> 所以我們也可以跟他們一樣做哪些事情

## 建議
現在: 身分認證跟安全混在一起講
可以考慮分開解釋
安全性:ex.按下投票時票會存在哪?背後對票的處理?

FIDO與FIDO2的比較，為什麼要升級、為什麼會存在?
加個why或summarize優缺點，做個比較就完成 -> 表格
[差別](https://www.1kosmos.com/authentication/fido2-authentication/)

安全晶片 要怎麼使用上去?直接寫到"總結以上四點..."後面，加個小結(也可以寫在研究方法)

預期結果有點短，可以寫這個系統可以為生活帶來甚麼方便?
ex.FIDO、安全晶片的優點可以帶來什麼方便

查證一下UAF的challenge/response機制(可以最後再做)
### 格式上的建議:
FIDO要全大寫
英文的名稱第一次出現要寫出全名與中文
沒有規定要標頁碼 -> 所以要標出來 方便討論

驗證器(authenticator) => 中文後面用括號補充英文會比較好，改掉像是Server,OS的簡寫
挑戰響應驗證機制(challenge & response)
### 下周
meeting暫停一周 大家對課表吧
FIDO實作?用在哪?原理?
安全晶片用在哪?怎麼用?

### 分工
第一次介紹名詞要寫完整(中英文) 大小寫要寫對(真的要用英文的話 第一個字母要大寫 e.g. "Web") 吳振群

預期結果 (技術和我們要做的事的連結，Note:不能寫太細，類似summary)祝語辰

安全晶片怎麼使用到我們的系統(ex.保護私鑰...) 簡弘哲

改UAF、標頁碼、FIDO跟FIDO2的比較 楊瑞凱

### reference
鮑嘉呈（2022）。基於Fido身份識別協定之行動應用使用者驗證機制設計。﹝碩士論文。國立臺北科技大學﹞臺灣博碩士論文知識加值系統。 https://hdl.handle.net/11296/85hpng。

安全晶片:

1. Hoffman, C. (2018, October 23). Your smartphone has a special security chip. here's how it works. How. Retrieved February 9, 2023, from https://www.howtogeek.com/387934/your-smartphone-has-a-special-security-chip.-heres-how-it-works/ 
2. Xin, X. (2018, October 17). Titan m makes Pixel 3 our most secure phone yet. Google. Retrieved February 9, 2023, from https://www.blog.google/products/pixel/titan-m-makes-pixel-3-our-most-secure-phone-yet/ 

FIDO U2F:

3. Srinivas, S., Balfanz, D., &amp; Tiffany, E. (Eds.). (2014, October 9). Universal 2nd Factor (U2F) Overview. Universal 2nd factor (U2F) overview. Retrieved February 10, 2023, from https://web.archive.org/web/20220214234755/https://fidoalliance.org/specs/fido-u2f-v1.0-ps-20141009/fido-u2f-overview-ps-20141009.html  

FIDO:

4. 羅正漢. (n.d.). 【全面解析FIDO網路身分識別】無密碼新時代將至！解決網路密碼遭竊與盜用問題. iThome. Retrieved February 10, 2023, from https://www.ithome.com.tw/news/128566 

---

# 0214 Update

## Outline
總結以前少做了甚麼，現在補齊了甚麼 / 對FIDO如何實裝的一些調查
1. Android Emulator login Lag
2. Google 登入
3. FIDO choosing
4. GOOGLE login & FIDO2
5. FIDO project

### Android Emulator login Lag

登入firebase會有問題(卡很久)，是因為android emulator sdk 31.3.10有bug，更新成最新版32.1.11即可解決(退回30.2.9)也可
結論：不是windows 11的問題，是emulator的問題。
Reference:
[1] [Firebase doesn't work on Android Studio Emulator](https://stackoverflow.com/questions/73370728/firebase-doesnt-work-on-android-studio-emulator)
Keyword: *android emulator cannot login firebase successfully*

### Google 登入

就如之前說的檢查四件事，是否開啟google 登入、是否填寫支援信箱、是否有設定好SHA1 finger print、以及設定好logo 
在確認好這四件事情後，就應該要可以登入了。
而且之前在測試其他Githib的模板時，就已經知道要將所有測試裝置的SHA1 fingerprint都要填上去。可還是出問題。

後來發現，OAuth 2.0 clientID，「套件名稱」和 fingerprint 的組合，不可以重複。因為，之前在測試別人的project時，有建另外一project，裡面的package name 一樣，然後測試時，error message 有寫(再添加fingerprint時)，但是我以為的意思卻與實際意義不同。刪掉別的project的OAuth 2.0 clientID，就可了。

Reference:
[2] [12500, an Android Developer’s nightmare…](https://dev.to/gattalraouf/12500-an-android-developer-s-nightmare-1i3b)
[3] [How multiple developers can work on the same android app connected to a single Firebase console?](https://stackoverflow.com/questions/54723123/how-multiple-developers-can-work-on-the-same-android-app-connected-to-a-single-f)

### Where to use FIDO? & Which FIDO protocol should we use?

目前傾向在登入的時候使用FIDO，會參考Hua_Wei寫好的FIDO package。
由於FIDO2可以經由打開瀏覽器的方式來完成認證，因此以FIDO2為目標。
[4] [huawei developer quick start](https://developer.huawei.com/consumer/en/doc/development/HMS-Plugin-Guides/integrate-fido-client-0000001077890662?ha_source=hms1)
[5] [package on pub.dev](https://pub.dev/packages/huawei_fido)

### About firebase authentication

有看到有人在[6]問說firebase是否支援FIDO2，大家的回答都是目前無法支援，但有其他種身分驗證的方式。而同時也有提到google auth並沒有辦法支援FIDO2，但這點chatGPT有不一樣的見解，它表示已經有支援，但是用戶要主動去設定，所以目前還不知道如何讓用戶強迫使用fido2.0登入，感覺是他們要自己設定。
最近的新聞[7]是2022/05/06，google才宣布要支援FIDO2標準。
:::spoiler firebase相關身分驗證
[firebase身分驗證](https://firebase.blog/posts/2022/07/new-firebase-auth-features)
![](https://i.imgur.com/adKPOgG.png)
![](https://i.imgur.com/bzWFuGb.png)
:::

:::spoiler google sign in with FIDO2.0
![](https://i.imgur.com/hvbBLIV.png)
:::

[6] [StackOverFlow: Firebase Fido2 Authentication Support](https://stackoverflow.com/questions/53709903/firebase-fido2-authentication-support)
[7] [蘋果、Google與微軟擴大對FIDO的支援以加速無密碼時代的到來](https://www.ithome.com.tw/news/150793)

### FIDO project

有找到現成的FIDO相關project[8]，目前跑不出東西。
這個project目的在模擬FIDO2的情形、展示FIDO2是否在登入時生效，現在跑不出來的狀況是，無法因為認證成功就print出正確的log。
找到問題了!問題在目前我生不出assetlinks.json檔案(~~keytools那邊有問題，refer to github~~)(此部分已解決)
![](https://i.imgur.com/iTzXJsU.png)

爬完文章後，產生金鑰的部分問題解決了[9]，但是
在生成assetlinks.json後，要host時出了困難。
目前暫時還沒有確認目前Google Cloud platform(google 提供的雲端運算服務)能否動。

所以測試時是先用localhost來測。
在此感謝ChatGPT提供的資訊，所以使用python 來測不用另外再import，就可以直接跑server。

然後就是跑了之後，發現第三個問題(不含其他因為repo使用舊的東東而報的錯)。

![](https://i.imgur.com/SCKgDZA.png)
第一個是因為repo的關係。實際上跳出來的error type ，repo並沒有handle，所以按下去沒反應。


第二個是要記得設定螢幕鎖定。

第三個是問題則是因為cross platform的關係
因為使用模擬器時，不能直接使用localhost，必須要使用ip才行(再次感謝ChatGPT指點)
所有和rpdomain 有關的都要改，此外package name app和 assetlinks要一致，
![](https://i.imgur.com/FAYNWc0.png)

可是會有問題的的地方就是，ip和locsalhost是cross platform的問題，目前就嘗試到這裡。
p.s.是有說到要怎麼改成"Access-Control-Allow-Origin"，但是因為現在還在探索FIDO如何實裝，不確定方向對不對，而且需要了解，他說要關掉的那些東西的風險，所以留待下周處理。
![](https://i.imgur.com/ktag0nX.png)

[8] [https://github.com/mojaloop/contrib-fido2-flutter-lib](https://github.com/mojaloop/contrib-fido2-flutter-lib)
[9] [How can I find and run the keytool](https://stackoverflow.com/questions/5488339/how-can-i-find-and-run-the-keytool)

## 下周目標
1. 百分比投票實裝
目前想法是保留現成的投票系統，以現在目前的版本為基礎，藉由更改數學運算方式與紀錄票數的資料結構，或許就可以達成。
2. FIDO現成project研究繼續
3. FIDO如何實裝

## 建議
1. 從OAuth來理解一下
2. 可以考慮google與FIDO2並行的模式
3. Access-Control-Allow-Origin了解
4. deeply-research in HuaWei API(原理)
5. 查看看臉部辨識、指紋辨識的相關API，看是不是能夠找到跟安全晶片互動的關鍵

---

# 0301 Update

## Outline
1. 報告百分比投票進度
2. OAuth
3. Access-Control-Allow-Origin
4. HuaWei API 原理講解
5. 臉部辨識、指紋辨識的相關API

### 百分比投票進度
目前的紀錄方式是開兩個table
一個是user，另一個是decision
decision裡面放了很多個vote uid，每個uid(一個row)裡面放了

1. isEnd
2. isPrivate
3. isSingle
4. pollWeights
5. title
6. uid: 紀錄誰創建這個vote
7. usersWhoVoted

![](https://i.imgur.com/pEuzsvi.png =50%x)

由於目前將usersWhoVoted這個column，以記錄選項string的方式來記錄狀態(儲存投票者投的字串來map到選項，也就是說只有: 有投、沒投這兩種情況)；而這個方法只能apply在沒有百分比的情況，因此，為了支援百分比投票，必須調整usersWhoVoted這個column。

目前: 還只有UI上的改動，還沒有真的更改

想法: 這就讓我們想到，是不是可以趁要調整的時候，調整整個decision存資料的方式。

~~目標: 先達成1st Normal Form，再看看要不要向上調整或是denormalize。~~

決定: 為了先做最小的改動，暫時先將```list<string>```改為```list< pair<string, int> >```

最後決定是FIDO2跟google登入並行的方式，接下來要報告我們google OAuth上禮拜沒看到的內容。

### OAuth
keyword: firebase->google cloud platform
#### 關於OAuth
對OAuth做了一些調查，詳細可以看以下兩篇新手教學文章
「我們允許並授權當前的應用程式（在這是指 Medium）有限度的取得我們在 Facebook、Google 或其他平台的相關資訊」
[認識 OAuth 2.0：一次了解各角色、各類型流程的差異](https://www.technice.com.tw/experience/12520/)
[Day07 - 【入門篇】什麼是OAuth](https://ithelp.ithome.com.tw/articles/10270271)
#### 放到Google Cloud Platform
在google cloud platform網頁上，有一些關於google auth的相關簡介
有一個特別的頁面專門用來處理auth相關驗證
![](https://i.imgur.com/9rqizMq.png)
接下來有發現一些Oauth的相關限制
![](https://i.imgur.com/URz7Vjw.png =80%x)
![](https://i.imgur.com/tWdej7O.png =80%x)

### FIDO2 Server
~~Access-Control-Allow-Origin~~[延後]
原本按照計畫應該是要將Access Control Allow Origin打開，但在測試前爬文的時候，發現說需要跑在FIDO2 Server上，我上週那樣子的那種local server目前應該是跑不動的，
![](https://i.imgur.com/nSasHvF.png)
因為我裡面除了assetlinks之外就沒有東西了。
於是重心就到了想辦法跑FIDO2 Server的Repo。
(Access Control Allow Origin的問題等FIDO Server能跑起來的時侯，因該還是會遇到，屆時在處理)
目前有找到 awesome-webauthn [1] 和 awesome-fido2 [2]
兩個彙整了FIDO2資訊的Repo。
目前在測試 [line-fido2-server](https://github.com/line/line-fido2-server)
目前進度時還在處理repo 使用的gradlew 版本與JVM不符的問題。
我這邊使用的Java 版本是18，但是原repo，gradlew6.7不支援。以下是要修改的地方
![](https://i.imgur.com/5YECs7d.png)
並且因為gradlew7.0之後 其中的一個plugin 'maven'被改掉了，改成'maven-publish' [3] 
所以當前因為maven-publish，build gradle部分code要改掉的問題。

目前在實作FIDO2 Project所參考的模板。
FIDO2 Client API: [contrib-fido2-flutter-lib](https://github.com/mojaloop/contrib-fido2-flutter-lib)
FIDO2 Server Example: [line-fido2-server](https://github.com/line/line-fido2-server)
目前應該使只要將line-fido2-server跑起來，讓Access-Control-Allow-Origin，應該是就沒問題了，而且有在line-fido2-server中找到要放assetlinks.json之處，解決了當初看readme時不知道如何host assetlinks.json的問題。
並且我們也現在可以從awesome-webauthn找到其他的repo，可以做為備案。

身分驗證看起來貌似就是生物辨識的部分。
![](https://i.imgur.com/b10pcgC.png)

要使用FIDO2，
- [X] 您需要有一個支援WebAuthn和CTAP的瀏覽器（例如Chrome、Firefox、Edge等）
- [X] - 以及一個符合FIDO標準的身分驗證器（例如YubiKey、Windows Hello等）=>生物辨識
- [X] 此外，您也需要有一個支援WebAuthn和CTAP的伺服器（例如StrongKey FIDO Server2），用來處理註冊和登入請求。

[1]  [awesome-webauthn](https://github.com/herrjemand/awesome-webauthn#tutorials) (Github)
[2]  [awesome-fido2](https://github.com/deepzz0/awesome-fido2) (Github)
[3]  [Plugin with id 'maven' not found](https://stackoverflow.com/questions/69100888/plugin-with-id-maven-not-found) (Stackoverflow)
[4] [Access-Control-Allow-Origin](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin)


### HuaWei API 原理講解
只要下一些指令就可以把此份plugin匯入到flutter的專案裡。
`This plugin enables communication between the HMS Core FIDO SDK and Flutter platform.` 不確定這些api是不是只能用在有HMS core的手機上，如果是的話，可能要可慮用其他方法實作。

![](https://i.imgur.com/I85ej2h.png)

---
此plugin的基本架構有以下幾點(要呼叫api需要用到的重要class)
- HmsBioAuthnManager
- HmsBioAuthnPrompt
- HmsFaceManager
- HmsFido2Client

#### bio_authn_manager.dart
目的 : 確認此手機是否有支援生物辨識方法
```htmlmixed=
Future<int?> canAuth() async {
    return await _channel.invokeMethod('canAuth');
  }
  ```
- invokeMethod可以讓android、ios原生的程式碼知道flutter要呼叫的方法是哪一個，也就是一座橋樑的概念，至於是怎麼連結兩者的目前沒有想法
#### bio_authn_prompt.dart
目的 : 呼叫指紋辨識的api
#### face_manager.dart
目的 : 呼叫臉部辨識的api
#### fido2_client.dart
目的 : 呼叫FIDO2 api，允許通過平臺身份驗證器或跨平臺身份驗證器進行註冊和身份驗證。

reference:
[huawei fido packge](https://github.com/HMS-Core/hms-flutter-plugin/tree/master/flutter-hms-fido)
[huawei api 簡介](https://developer.huawei.com/consumer/en/doc/development/HMS-Plugin-References-V1/overview-0000001096697417-V1)

### 臉部辨識、指紋辨識的相關API
我先找出較熱門或是最近有更新的package，再去每一個package的github repo看source code imports，看他們有使用到其他哪些可能跟安全晶片有關的package，但目前看下來較多的只有2個flutter library --- services, foundation
[services, foundation library ref](https://api.flutter.dev/index.html)
(目前還沒試用過底下這些package，只有看source code)

翻了一些套件後發現跟加密有關的都只有實作演算法的部分，沒看到裡面的code有去跟安全晶片做互動。

另一個發現是有些套件裡的function如下圖所示沒有實作細節，感覺是要留給使用者去自己定義，因此也無法從這些套件的function中去看到安全晶片的蹤跡
![](https://i.imgur.com/fgHXJpp.png)

keyword: biometric, crypto, auth

[local_auth](https://pub.dev/packages/local_auth)
[flutter_screen_lock](https://pub.dev/packages/flutter_screen_lock)
[biometricx](https://pub.dev/packages/biometricx)
[flutter_reprint](https://pub.dev/packages/flutter_reprint)
[biometric_fingerprint](https://pub.dev/packages/biometric_fingerprint)
[http_certificate_pinning](https://pub.dev/packages/http_certificate_pinning)
[flutter_locker](https://pub.dev/packages/flutter_locker)
[flutter_local_auth_invisible](https://pub.dev/packages/flutter_local_auth_invisible)
[native_auth](https://pub.dev/packages/native_auth)
[local_auth_crypto](https://pub.dev/packages/local_auth_crypto)
[biometric_auth](https://pub.dev/packages/biometric_auth)
[flutter_local_authentication](https://pub.dev/packages/flutter_local_authentication)
[pin_lock](https://pub.dev/packages/pin_lock)
[webauthn](https://pub.dev/packages/webauthn)

[local_biometrics_auth](https://pub.dev/packages/local_biometrics_auth)

- 裡面用到的[flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage)有提到android把key存在[KeyStore](https://developer.android.com/training/articles/keystore) (Android Keystore system)裡面

[flutter_biometrics](https://pub.dev/packages/flutter_biometrics)
- 利用生物特徵進行辨識並產生金鑰&進行加密，Heavily influenced by local_auth

[biometric_signature](https://pub.dev/packages/biometric_signature)
- 與1.類似

[pointycastle](https://pub.dev/packages/pointycastle)
- 有許多的加密algo，但其repo size非常大，有幾百個dart file所以還沒有trace
    
## 下周目標
1. 百分比 -> 先讓原本的code在經過調整之後可以跑

## 建議
1. fido client server連接
2. 往別的code去找安全晶片api
3. 繼續挖挖看biometric
4. 繼續跑server那份code(留意server提供哪些路徑、收甚麼參數；client送了哪些東西出去)
5. flutterpluginloginapi這個API是寫死的
6. webauth
7. register btn & sign btn很重要
8. 獨立研究flutter_biometrics(學長想要聽細節)，如何取得那把key

---

# 0307 Update

## Outline
1. overview
2. flutterpluginloginapi
4. server code
5. 安全晶片API(其他語言的)
6. flutter_biometrics

### overview
[overview](https://hackmd.io/@zRWCfXc1TOaCsnINOAPeCw/HkkDB4G12)

### flutterpluginloginapi(楊)
1. 從以下的教學內文中，並沒有辦法很直接地得知這個API使用FIDO
2. 可以參考，但他只支援Android；因此IOS裝置的部分就需要再想其他方法(或是參考這個刻一個)

[中文教學](https://www.bing.com/search?q=flutterpluginloginapi&cvid=76ba0e2e9ded46708439c893b40e86c0&aqs=edge..69i57j0l8.373j0j1&pglt=41&FORM=ANSPA1&PC=ASTS)

### server code(祝)
Fork Line 的 server，然後修改rpeserver, server, line-fido-spring-bootstarter資料夾中的
gradle-wrapper.properties => gradle版本升級 (參考之前)
升級之後 build.gradle()(三份都是) 中maven plugin都要改成'maven-publish'
又因為有一些method要被放棄，所以要改成新的(參考下文)
Ref[Could not find method compile() for arguments Gradle](https://stackoverflow.com/questions/23796404/could-not-find-method-compile-for-arguments-gradle)
最後lombok1.18.16=>1.18.20(修改build.gradle中的部分)
Android Emulator API 必須為31, 這樣子才能裝最新版的Chrome, 但是Chrome 在Api 31又有一點小問題記得處裡。
[Google Chrome browser in Android 12 emulator doesn't load any webpages (internet is working!) ](https://stackoverflow.com/questions/69134922/google-chrome-browser-in-android-12-emulator-doesnt-load-any-webpages-internet)
這樣就能跑，But,
![](https://i.imgur.com/p4nch9c.png)
![](https://i.imgur.com/TrP9lst.png)



### 安全晶片API(吳)
問題:
1. 所謂的安全晶片是什麼意思?像iphone12採用A15仿生晶片，這個晶片就是安全晶片嗎?
2. 如果每一種品牌的手機會使用不同的安全晶片，那這樣要怎麼找api?

並未找到針對特定安全晶片的api。
flutter的官網有講解到可以用api跟原生語言溝通就好，而且是溝通整個android或ios平台，但似乎也不是直接跟安全晶片溝通。

### flutter_biometrics(簡)
google: `what is the purpose to use methodchannel in flutter`
一些關於Flutter service lib MethodChannel 參考資料:
[Flutter 與 Android、iOS 溝通方式](https://ithelp.ithome.com.tw/articles/10262389)
[github blog tutorial](https://github.com/Nash0x7E2/Flutter-method-channel-tutorial/blob/master/blog/28418.md)
[medium tutorial](https://medium.com/47billion/creating-a-bridge-in-flutter-between-dart-and-native-code-in-java-or-objectivec-5f80fd0cd713)
[short example](https://mobikul.com/method-channel-flutter/)
[MethodChannel & EventChannel](https://invertase.io/blog/flutter-native-apis-pt1)

這禮拜仔細trace上面的package後發現重點不是在它import了哪些東西，而是在每個function中有運用到的
`MethodChannel invokeMethod(...)`
它讓Flutter可以根據用戶手機的平台去決定要呼叫哪個API(Android or IOS)，我們只需要在Flutter project中的android, ios資料夾中去用原生語言實作細節即可。

觀察了上面package的android,ios資料夾後發現原生語言有提供關於security的library，但我目前還沒針對這些原生library去深入探究
![](https://i.imgur.com/W46QEE4.png)
![](https://i.imgur.com/fYSWFFA.png)


1. **Flutter & Android,IOS的互動方式:**
Flutter利用message-passing的方式透過MethodChannel傳送到Android or IOS去呼叫原生API，最後再將結果送回Flutter。
Flutter中的每個資料型別再其他語言中都有一一對應，不用擔心型別轉換的問題

2. **MethodChannel的建立方式:**
MethodChannel藉由channel name將client跟platform(Android, IOS)連接起來。
因此在同一個app中，如果有用到多個MethodChannel的話，那每個channel name必須都不一樣
(但我看上面那些package整份project中只用到一個MethodChannel

3. **透過invokeMethod呼叫原生API:**
在撰寫Flutter App時將function name當作字串傳進invokeMethod中，然後去project底下Android與IOS的資料夾中使用原生語言(Kotlin, Swift)去實作原生API。
下圖是來自官方說明文件，++要注意的是使用模擬器去測試invokeMethod的話有可能會失敗++
![](https://i.imgur.com/Ds1ArLz.png)

更多關於MethodChannel的資訊可以參考[Flutter docs 說明&教學](https://docs.flutter.dev/development/platform-integration/platform-channels)

## 下周目標

## 問題
可以問的問題: 
1. 是否可以FIDO用一個資料庫、投票相關的資料放在firebase?
2. 有沒有甚麼替代firebase的方案?
3. (不是問題)flutter備案: cordova

## 建議
安全晶片的意思?
A15不是安全晶片，安全晶片建立在A15的一個小區塊。
每個品牌的手機的安全晶片不一樣，API會不一樣嗎?
call API可以解決這件事情；因此使用安全晶片會交給OS，我們只需要call API(By using or calling invokeMethod)
只要能確定這個API能夠使用安全晶片來加解密，就行了。
兩個server(web server & auth server)這件事情是可能的!
因為支援客製化的token。
自己找Flutter package(Android的跟瀏覽器的差不多；IOS...?)
Android API就是FIDO2(會判斷手機有沒有安全晶片；如果有安全晶片的話，他的API就會自己在安全晶片處理簽名)，不用管怎麼簽名，只要知道API怎麼傳參數。
IOS的API就要找一下。google-identity-fido，refer to 學長的github。目前只確定安卓有FIDO。

所以先讓FIDO協定可以通，之後再想說要怎麼計算簽名之類的(現在是寫死的)

---

# 0314 Update

## Outline
1. 每個人都可以跑server
2. 找firebase支援客製化token(server用甚麼方式做出token、怎麼傳給firebase)
3. 看android的github來找android fido API
4. 找IOS的API


## firebase支援客製化token(楊)
JS的作法
[創建自定義令牌](https://firebase.google.com/docs/auth/admin/create-custom-tokens?hl=zh-tw)
[使用自定義身份驗證系統在 JavaScript 中使用 Firebase 進行身份驗證](https://firebase.google.com/docs/auth/web/custom-auth?hl=zh-tw#:~:text=Authenticate%20with%20Firebase%201%20When%20users%20sign%20in,to%20signInWithCustomToken%20to%20sign%20in%20the%20user%3A%20)
Flutter的作法
官方文件: [Authenticate with Firebase Using a Custom Authentication System](https://firebase.flutter.dev/docs/auth/custom-auth/)
[Using Custom Authentication in Flutter SDK](https://web3auth.io/docs/sdk/flutter/custom-authentication)

1. server用甚麼方式做出token
[Generate Token using the Flutter Application - Agora](https://stackoverflow.com/questions/66920476/generate-token-using-the-flutter-application-agora)
Stackoverflow上的做法是使用Agora-flutter，而Agora這個SDK主要是用來實作video chat的package，裡面也有用到auth token
[how to build a Agora server](https://www.agora.io/en/blog/how-to-build-a-token-server-using-golang/)
在官方文件中，它提供了如何建立token的教學、流程圖
![](https://i.imgur.com/MWXt9Ou.png)
```code=
public class App {
    static String appId = "Your app Id";
    static String appCertificate = "Your app certificate";
    static String channelName = "Your channel name";
    static int uid = 0; // The integer uid, required for an RTC token
    static int expirationTimeInSeconds = 3600; 
    // The time after which the token expires

    public static void main(String[] args) throws Exception {
        RtcTokenBuilder2 tokenBuilder = new RtcTokenBuilder2();
        // Calculate the time expiry timestamp
        int timestamp = (int)(System.currentTimeMillis() / 1000 
                            + expirationTimeInSeconds);

        System.out.println("UID token");
        String result = tokenBuilder.buildTokenWithUid(appId, appCertificate,
                channelName, uid, Role.ROLE_PUBLISHER, timestamp, timestamp);
        System.out.println(result);
    }
}
```
Agora提供了驗證token的服務，可以選要用哪一種
![](https://i.imgur.com/saunmeQ.png =40%x)
token server也可以自己寫(寫關於authentication service)
![](https://i.imgur.com/baILQdn.png)
[Agora官方文件](https://docs.agora.io/en/video-calling/develop/authentication-workflow?platform=android)
以下是Flutter接收來自Agora的token的方法
```code=
String baseUrl = ''; //Add the link to your deployed server here
int uid = 0; 
String token;

Future<void> getToken() async {
   final response = await http.get(
     Uri.parse(baseUrl + '/rtc/' + widget.channelName 
             + '/publisher/uid/' + uid.toString()
          // To add expiry time uncomment the below given line 
          // with the time in seconds
          // + '?expiry=45'
          ),
    );

    if (response.statusCode == 200) {
      setState(() {
        token = response.body;
        token = jsonDecode(token)['rtcToken'];
      });
    } else {
      print('Failed to fetch the token');
    }
 }
```
2. 怎麼傳給firebase
程式碼大概長這個樣子，裡面使用了官方文件支援的API(signInWithCustomToken)
```code=
try {
    final userCredential =
        await FirebaseAuth.instance.signInWithCustomToken(token);
    print("Sign-in successful.");
} on FirebaseAuthException catch (e) {
    switch (e.code) {
        case "invalid-custom-token":
            print("The supplied token is not a Firebase custom auth token.");
            break;
        case "custom-token-mismatch":
            print("The supplied token is for a different Firebase project.");
            break;
        default:
            print("Unkown error.");
    }
}
```
結論: firebase在接收token上已經有東西可以使用了，應該不成問題；重點應該是在server side(how to generate token)以及自己寫authentication service。

## 看android的github來找android fido API(簡)
[android github](https://github.com/android/identity-samples)
- [security samples](https://github.com/android/security-samples)
- [identity samples(FIDO2)](https://github.com/android/identity-samples)

## refs:
[FIDO2 API intro.](https://developers.google.com/identity/fido/android/native-apps)
[FIDO2 API codelab教學](https://codelabs.developers.google.com/codelabs/fido2-for-android#0)
[WebAuthn codelab教學](https://developers.google.com/codelabs/webauthn-reauth/#0)
[FIDO & FIDO2 api docs](https://developers.google.com/android/reference/com/google/android/gms/fido/Fido)

額外找的android, java security lib
[android security docs](https://source.android.com/docs/security)
[使用Android KeyStore 儲存敏感性資料](https://medium.com/joe-tsai/%E4%BD%BF%E7%94%A8keystore-%E5%84%B2%E5%AD%98%E6%95%8F%E6%84%9F%E6%80%A7%E8%B3%87%E6%96%99-92ad9b236e58)
[android.security.keystore ref](https://developer.android.com/reference/android/security/keystore/package-summary)
[java.security](https://developer.android.com/reference/java/security/package-summary)

## 找IOS的API(吳)

refs:
[IOS with FIDO2 github](https://github.com/singularkey/iosfido2demo)
[yubikit-ios](https://github.com/Yubico/yubikit-ios)
[ios官網](https://developer.apple.com/documentation/authenticationservices/public-private_key_authentication/supporting_security_key_authentication_using_physical_keys)
## 下周目標

## 建議
1. 報告的點signInWithCustomToken之後firebase要怎麼認定這個token是否有效
2. 兜出完整流程圖，解釋一下哪個技術要用在哪邊、哪個功能需要甚麼技術、使用者會怎麼使用，最後做出Todo-list
3. 可以只暫時focus在Android或是先跑web的project
4. 跑一個FIDO2的project，架前後端的那種
5. 找資料的過程中，要想說這個project的定位(只涵蓋一點點嗎?還是很有價值?)

---

# 0317 Update

## Outline
1. 流程圖
2. signInWithCustomToken
3. LineServer

## 流程圖
```mermaid
flowchart TD;
登入頁面-->Register-->生物辨識創建公鑰/私鑰對-->公鑰加密後傳給TokenServer-->TokenServer的KeyList新增這個公鑰-->登入頁面;
登入頁面-->A[Log in]-->使用者向TokenServer發一個請求-->TokenServer查是否註冊過\n傳回Challenge-->生物辨識來選擇私鑰\n使用者使用私鑰簽名\n傳Response到TokenServer-->TokenServer用公鑰計算Response\n若正確則TokenServer產生token-->給firebase\n驗證有效性-->成功登入;
```
```mermaid
flowchart TD;
投票頁面-->創建投票-->將標題與選項傳入firebase-->Z[firebase紀錄標題 選項 創建者 投票者投的選項];
投票頁面-->參與投票-->輸入邀請碼\n或藉由QRCode獲得邀請碼-->從firebase找到對應投票並顯示-->將投票選項update到firebase的選項;
投票頁面-->查看結果-->從firebase找到已參與投票並顯示結果;
```
Challenge/Response
1） 用戶端向伺服器發出認證請求;
2） 認證伺服器從使用者資料庫中查詢使用者是否是合法的使用者，若不是，則不做進一步的處理;
3） 認證伺服器內部產生一個隨機數，作為Challenge，發送給使用者;
4） 客戶將名字和隨機數合併，使用單向Hash函數（例如MD5演算法）生成一個字串作為Response;
5） 認證伺服器將Response與自己的計算結果比較，如兩者相同，則通過一次認證，反之認證失敗;
6） 認證伺服器通知客戶端認證成功或失敗。

ref:
[How fido works](https://fidoalliance.org/how-fido-works/)
系統會提示用戶選擇一個符合在線服務接受政策的可用FIDO認證器。
用戶使用指紋讀取器、第二因素設備上的按鈕、安全輸入的PIN或2其他方法解鎖FIDO認證器。

用戶的設備為本地設備、在線服務和用戶帳戶創建一個新的公鑰/私鑰對。
公鑰發送到在線服務並與用戶帳戶關聯。私鑰和有關本地身份驗證方法的任何信息都不會離開本地設備。
要登錄，在線服務會挑戰用戶使用符合其接受政策的先前註冊的設備。
用戶使用與註冊時相同的方法解鎖FIDO認證器。
設備使用服務提供的用戶帳號標識符選擇正確的密鑰並對其挑戰進行簽名。
客戶端設備將已簽名的挑戰發送回服務，該服務使用存儲的公鑰進行驗證並登錄用戶。

keyword: [custom token 一次性],[JWT]

## signInWithCustomToken(楊)
API不會驗證token的有效性，也有查到這個Token一般來說是JWT格式。
Token有可能會出現過期的情況，網路上有一些關於Token續命的討論，但我沒有辦法分辨正確性。
[淺談 Session 與 JWT 差異](https://medium.com/@jedy05097952/%E6%B7%BA%E8%AB%87-session-%E8%88%87-jwt-%E5%B7%AE%E7%95%B0-8d00b2396115)
[关于Token 自动续期的解决方案](https://zhuanlan.zhihu.com/p/163053370)

## LineServer

## 下周目標

## 建議

---

# 0329 Update

## Outline
1. JWT(關於怎麼做)
2. 有沒有token server跟FIDO合一的現成專案
3. LineServer跑不出來的原因總結

### JWT(楊)
0. 使用JWT的原因
因為firebase沒有辦法處理FIDO2，因此必須自行架設server來專門驗證；而驗證之後，需要將使用者資訊傳給firebase，因此JWT在這邊扮演的腳色是傳遞資料(Token)給firebase。
了解JWT可以讓我們之後在製作custom token時更快知道如何操作。

1. 結構
JWT 的組成內容有三個部分(header, paylord, signature)，由" . "做區隔，最後透過這三個部分，串成一個 Jwt 字串
paylord部分有三種: Reserved, Public, Private
signature有三部分: header, paylord, secret
secret要放在server端，JWT的簽發驗證都必須使用這個secret，當其他人得知這個 secret，那就意味著客戶端是可以自我簽發jwt，因此在任何場景都不應該外流
JWT會使用base64加密將這三個部分串起來。

2. 流程
![](https://i.imgur.com/WziaIJc.png)
實作的code在[3]

3. 怎麼驗證
![](https://i.imgur.com/3PBGGAN.png)
有人在stackoverflow[1]提出是不是可以從firebase找到JWT的secret，而在回答中，似乎獲得了一個可行的方案來獲得JWT。
因此又回去看firebase的官方文件，就找到了其實firebase有能力能夠驗證這個token
![](https://i.imgur.com/NGwggbA.png)

reference:
[1\ Where do you get/find the JWT-Secret from firebase?](https://stackoverflow.com/questions/58399462/where-do-you-get-find-the-jwt-secret-from-firebase)
[2\ JSON Web Token(JWT) 簡單介紹](https://mgleon08.github.io/blog/2018/07/16/jwt/)
[3\ JWT(JSON Web Token) — 原理介紹&實作JWS](https://yen0304.github.io/p/jwtjson-web-token%E5%8E%9F%E7%90%86%E4%BB%8B%E7%B4%B9%E5%AF%A6%E4%BD%9Cjws/)
[4\ JWT authentication: Best practices and when to use it](https://blog.logrocket.com/jwt-authentication-best-practices/)
[5\ Week12 - 要在不同Server間驗證JWT好麻煩嗎？RS256提供你一種簡單的選擇 - JWT篇 [Server的終局之戰系列]](https://ithelp.ithome.com.tw/articles/10231212)

### token server跟FIDO合一的現成專案(簡、吳)
github keyword: fido token

用fido token找的大部分結果都是利用U2F協議，沒有看到fido2

用fido server找會找到滿多東西

[StrongKey fido2](https://github.com/StrongKey/fido2)
這個github repo中沒有source code，只有demo的網頁連結。
從README提到的SourceForge載點下載下來的壓縮檔也只有`.sql, .jar`檔案而已。
他的code似乎是用svn(Subversion)去做版本控制而不是用git，但SourceForge上的Code link似乎已經失效因此用svn也沒辦法抓下來

https://github.com/webauthn-open-source/fido2-server-demo
需要先安裝一些東西如npm, docker

![](https://i.imgur.com/vsjahJd.png)

這份project的擁有者目前還沒在windows上測試過，不確定到時候能不能跑起來。

---
[some fido servers](https://github.com/deepzz0/awesome-fido2)

[strong key demo](https://demo.strongkey.com/basicdemo/) : 輸入自己的email之後會要求你存取指紋，註冊成功後登入也只需要輸入email然後驗證指紋，就不用再輸入密碼了。有查到[strong key的做法](https://demo4.strongkey.com/getstarted/#/Accessibility/post_ping)，但目前還沒有理解。

[WebAuthn.io](https://webauthn.io/)
有許多不同語言寫成的server，不確定我們的專題需不需要用到。


### LineServer跑不出來的原因總結
1. 哪裡有問題、有嘗試過怎麼解決
在 LineServer中，總共有提供三個模板，而我們主要在嘗試跑的是第一個(rpserver)，因為他是一個完整的範例，
所以以此為目標，之前學長有說過可能是其中另外一個port被擋住，
![](https://i.imgur.com/VItTSWk.png)
然後再重新檢視每一段Github repository後，是因為忽略要安裝h2_database。
以為說是windows本地端就有。
![](https://i.imgur.com/Wsbi1AD.png)

所以關於為什麼跑不起來的原因，可能是因為
*  防火牆擋住(port)
    ![](https://i.imgur.com/xXZfc1I.png)
基本確認是這個port被擋住，但是不是其實h2database有跑起來，因為防火牆擋住這還不確定。
*  另外就是因為沒有裝h2_database，所以拒絕連線。
[h2database](https://github.com/h2database/h2database)
這個是h2_database 官方的github，從這可以連去官網下載。
下載之後，拉下來跑，~~但是最後還是沒辦法連進去~~。
![](https://i.imgur.com/ZeUI6jT.png)
![](https://i.imgur.com/ogteJxc.png)
![](https://i.imgur.com/4KPeYmg.png)
![](https://i.imgur.com/irPd1MD.png)

![](https://i.imgur.com/ISSZzDg.png)
連進去了，但是Filed not found.
![](https://i.imgur.com/jjDKnl8.png)
[H2資料庫安裝部署及簡單使用](https://blog.csdn.net/sdujava2011/article/details/114522248)


## 下周目標

## 建議

---

# 0405 Update

## Outline
1. webAuthn + token 評估可能性
2. strong-key SourceForge(跑+找有沒有source code)
3. CTAP

### webAuthn + token 評估可能性 (吳)
要做的事情 : 了解各個repo在幹嘛以及盡量理解背後的運作原理，這樣才能知道flutter要怎麼和這些repo溝通。

![](https://i.imgur.com/wyyDNQi.png =35%x)
**內容** :
including security keys, Touch ID, Face ID, Windows Hello, Android biometrics...and pretty much everything else.

**問題** : 
設定環境的時候有一個指令會報錯，目前還沒有解決方法。

**可行性** :
未知

![](https://i.imgur.com/MjsMKq1.png =35%x)
**內容** :
Yubikey跟生物辨識都有

**問題** : 
在跑範例的時候不知道為什麼'go run'這個指令會報錯。

**可行性** : 
有一個簡單的範例教學(前端用html，後端用Go)，且把一步一步的程式碼在做什麼事情都詳細列在一個網站上，或許可以參考這一份repo作為我們了解webauthn運作的基礎。[link](https://www.herbie.dev/blog/webauthn-basic-web-client-server/)

[Go installation](https://bobbyhadz.com/blog/go-is-not-recognized-as-internal-or-external-command)

### strong-key SourceForge(簡、楊)
1. 更正
後來發現在SourceForge上下載的壓縮檔裡面就有source code，就不需要用svn去抓了
![](https://i.imgur.com/ob5YXG3.png)
2. 動機
為什麼需要研究strong-key?
因為想要從strong-key這份project裡面，知道之前說過的流程細節該如何處理，並且知道哪些功能該在哪邊實作
3. 可以參考的部分
JWT.java(java實作部分)
    - getHeader
        處理header相關資訊
    - getBody
        處理body相關資訊
    - VerifySignature
        根據不同的algorithm apply不同的方法
        他的驗證算法是import java security來的，不是自己寫的
4. 小結
先以Go, python的那兩份為主，如果不行的話再考慮跑這份並且trace code(檔案過大)

### CTAP(Client to Authenticator Protocol) (祝)
1. 先說結論:

    理解這個協定，可以幫助我們了解FIDO2運作，以及它確實會是我們的專題中會需要用到的東西，但是我們不需要實際去實作它。
    
2. What is CTAP?


    CTAP是客⼾端到⾝份驗證器協議 (Client to Authenticator Protocol)的縮寫。
    顧名思義，就是在規範，Client端和驗證器之間的溝通時，要遵照的流程，以及特定的格式。
    
    * CTAP1 v.s. CTAP2:
    
        |     版本     |          CTAP1          |               CTAP2                |
        |:------------:|:-----------------------:|:----------------------------------:|
        | 實作的驗證器 | U2F/CTAP1 authenticator | CTAP2/FIDO2/WebAuthn authenticator |
        |     備註     |      也被稱作 U2F       |       和WebAuth共同組成FIDO2       |
    
    * CTAP's Component:
        
        |       Component       |        Example        | For our cases |
        |:---------------------:|:---------------------:|:-------------:|
        |      Rely Party       | native app or website |  voting app   |
        |    Client Platform    |          PC           |  Smart phone  |
        | Roaming Authenticator |      Smart phone      |  Smart phone  |

    * CTAP's Structure:
        * Authenticator API:
            概念上類似API，但是由實作的platform提供。
        * Message Encoding:
            host(platform)要把請求按照什麼格式編碼之後，傳給Authenticator。
        * Transport-specific Binding:
            platform可以透過那些方式(USB, NFC, Bluetooth)將資料傳給Autheticator。


3. CTAP在我們的專題中，預期會扮演什麼角色?

    在我們的voting app調用手機的相應的API後，我們的手機就會遵照這個protocal和Autheticator作**連接**，所規範的是兩者之譏的連接方式。沒有這個protocal，我們的手機沒辦法(?)和Autheticator 連結。
    
4. 我們為什麼不需要實作它?

    從protocal的Overview中我們會發現，CTAP的protocal 很大的部分都是由所使用的client platform來提供，而不是我們應用層(voting app)，在我們**voting app要處理的只有調用平台的等效的API。**
    其餘部分按照Spec的介紹都是由客戶端平台本身啟動ex.憑證管理、PIN 建立/維護或生物特徵登錄。
    平台會根據我們的Relying Party所傳遞的資訊來做進一步的處理。
    
6. What's next?

    - 確認我們所選擇的client platform(android 手機)會和Spec所說的一樣，會處理後續的問題，因為Spec的用詞是"通常"。
    - 對於用手機作為Authenticator，以Android來說，Authenticator是不是已經寫好，是否會在我們調用API時，就同步處理以及具體是怎麼實作。
    - ~~找到native app 在andoid 平台中，與website時調用的navigator.credentials.create() or navigator.credentials.get() 等效的API。~~ --> 之前大家就有找到過了
    
7. Notice!
    
    所謂的Authenticator API，按照Spec說的，好像會和WebAuth ~~有重疊。~~(相符)
********
8. Reference:
    * [Client to Authenticator Protocol (CTAP)](https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-errata-20220621.pdf)
    * [Relying Party為本地應用程序時在憑證註冊或身份驗證的Client platform API(by簡,0314)](#看android的github來找android-fido-API(簡))

## 下周目標

## 建議

---


# 0418 Update

## Outline
1. Python WebAuthn
2. Go 架構圖
3. Go security-library
4. Python JWT

### Python WebAuthn
這份是在WebAuthn.io上的python repo，只需要按照Readme.md的步驟安裝與建立虛擬環境就可以跑起來。

1. 目前還沒有仔細trace code
2. 我是用windows上的cmd去跑，至於能不能用vscode中的ternimal去跑?目前不知道

python 虛擬環境安裝&使用 ref:
[medium](https://medium.com/ai-for-k12/python-%E7%9A%84-virtualenv-%E8%99%9B%E6%93%AC%E7%92%B0%E5%A2%83%E5%AE%89%E8%A3%9D%E8%88%87%E4%BD%BF%E7%94%A8-8645f5884aac)
[blog](https://simplelearn.tw/2022/08/08/python-%E8%99%9B%E6%93%AC%E7%92%B0%E5%A2%83%E5%AE%8C%E6%95%B4%E6%95%99%E5%AD%B8-1%EF%BD%9Cvirtualenv-%E8%99%9B%E6%93%AC%E7%92%B0%E5%A2%83%E5%AE%89%E8%A3%9D%E5%8F%8A%E4%BD%BF%E7%94%A8/)
[iT邦幫忙](https://ithelp.ithome.com.tw/articles/10199980)

至於Go的那份範例可以成功註冊，不過註冊完vscode terminal噴一堆error，目前無法登入

### GO跑出來的結果截圖
![](https://i.imgur.com/I4Q9RpC.png)
![](https://i.imgur.com/ymbqQMC.png)
![](https://i.imgur.com/f7JSoJj.png)
![](https://i.imgur.com/HzWhmbI.png)
![](https://i.imgur.com/jbSNKQR.png)
![](https://i.imgur.com/EXGlTDd.png)
![](https://i.imgur.com/z4VYAeM.png)
![](https://i.imgur.com/NidZY5I.png)
![](https://i.imgur.com/y6Op7nf.png)

### GO架構圖
觀察webauthn-example main in server.go
```mermaid
flowchart TD;
A[webauthn obj create] -->
B[userdb] -->
C[session keystore] -->
D[new router] -->
E[beginRegister] -->
F[finishRegister];
D[new router] -->
G[beginLogIn] -->
H[finishLogIn];
```
FIDO部分都直接call webauthn API
1. beginRegister:
```mermaid
flowchart TD;
A[check existence of user] -->
B[registerOption] -->
C[預先處理credential, session data \nby calling webAuthn.BeginRegistration] -->
D[沒有錯誤則send http response] -->
E[store session data] -->
F[store status]
```
2. finishRegister:
```mermaid
flowchart TD;
A[check existence of user] -->
B[load session data] -->
C[add credential] -->
D[success register]
```
3. beginLogIn:
```mermaid
flowchart TD;
A[check existence of user] -->
B[registerOption] -->
C[預先處理credential, session data \nby calling webAuthn.BeginRegistration] -->
D[沒有錯誤則send http response] -->
E[store session data] -->
F[store status]
```
4. finishLogIn:
```mermaid
flowchart TD;
A[check existence of user] -->
B[load session data] -->
C[check credential\ncredential counter increase] -->
D[success login]
```
### GO的security-library(楊)
[How to verify JWT signature with JWK in Go?](https://pkg.go.dev/github.com/dgrijalva/jwt-go)
[crypto](https://pkg.go.dev/crypto#section-documentation)
[JWK](https://pkg.go.dev/github.com/lestrrat-go/jwx/jwk)

JWK作用:
1. JSON轉換
2. Raw Key Type轉換
Raw Key Type有支援: RSA, EC(P-256,P-384,P-521)

CRYPTO作用:
1. hash
2. 有定義public & private key的type
3. Signer
4. decrypt
![](https://i.imgur.com/0QQFysp.png)

JWT-GO作用:
專門用來處理JWT的package(Signing method等)
![](https://i.imgur.com/a3iIWvl.png)

### Python JWT
手把手教學: [How to Handle JWTs in Python](https://auth0.com/blog/how-to-handle-jwt-in-python/)
看code: [refering github page](https://github.com/auth0-blog/jwts-in-python)
更詳細的說明(又重新講了一遍JWT)，重點在於有實作例子: [淺談JWT的安全性與適用情境](https://medium.com/mr-efacani-teatime/%E6%B7%BA%E8%AB%87jwt%E7%9A%84%E5%AE%89%E5%85%A8%E6%80%A7%E8%88%87%E9%81%A9%E7%94%A8%E6%83%85%E5%A2%83-301b5491b60e)
![](https://i.imgur.com/9EqlS4Y.png)

---

# 0425Update

API的port是不是一樣的? 可不可以嘗試使用GO那份的HTML+Python後端測試看看
可以嘗試比較Python跟GO有沒有不一樣(架構圖照抄)
研究看看GO的error message(可能是code沒寫完或是有東西沒接好)

## Outline
1. 上次那份python project的simple demo
2. python project(webauthn_form.html) code-tracing
3. 研究看看GO的error message

### 上次那份python project的simple demo(跑不出來 無法demo)
有找到webauthn.io上面的html(使用Django package來與HTML互動) [github](https://github.com/duo-labs/webauthn.io)
位置在```/_app/homepage/templates/homepage/sections```
裡面寫的很詳細，連profile都有做出來
但現在demo還跑不出來，癥結點在於，我們照著README去做之後，還是跑不出來。
它的README寫得太過簡短；也有問過chat-gpt，他給的意見都不太可行；目前經過trace code之後，還是沒搞懂要怎麼跑起來這份project。

### python project(webauthn_form.html) code-tracing
主要跟FIDO相關的是webauthn_form.html。它的作法其實跟之前的差不多，有get/post。
與GO的差異在於，這份寫得相較之下更細一點: 除了register, authenticate，還有setup algorithm(說白了就是它用flag來設定option)、verifyJson的相關function(它verify的時候，就直接用Json格式了，因此說不定在JWT的token轉換上，會讓整件事情變得更簡單一點?)

get的部分跟GO其實差不多。
![](https://i.imgur.com/vKws5Kb.png)

在放資料時，把資料包成一包之後，轉成json。接著將這個json格式放到option裡面。
![](https://i.imgur.com/V3PquRl.png)

最終會把option餵到simplewebauthnbrowser中。
![](https://i.imgur.com/jUQN3m8.png)

定義simplewebauthnbrowser的是一份js檔案
(他的長相只有一行 超醜 就不附上了)

submit response的時候一樣也是轉成json。
![](https://i.imgur.com/p8vcxnT.png)

也就是說，這份project只差將token server的功能(變成firebase custom token能夠接收的格式)補上，基本上就可以使用了。//還是建立在這份跑得起來的情況下

### 研究看看GO的error message
在一長串的錯誤訊息中，大部分都是如
`fp=0x... sp=0x... pc=0x...`
之類的底層錯誤訊息，唯一較高階的錯誤是
`msg="Error getting session securecookie: the value is not valid"`

目前猜測導致此錯誤的原因有2個:

1. 沒有將第三方package升級到最新版本
在這個[討論](https://blog.csdn.net/zzsan/article/details/128551246)中有提到這個問題，而這份go example使用已經deprecated的webauthn repo，所以我在想其中一個可能的原因是這個。
或許只要把deprecated repo migrate到目前的發行版本就可以解決(有做一些嘗試)

2. 3rd party package
還有一個可能的原因是這份repo所使用到的
`github.com/gorilla/sessions v1.1.3 // indirect`
在這個gorilla的[issue](https://github.com/gorilla/sessions/issues/16)中有提到一樣的錯誤訊息
但我目前不知道錯誤訊息是因為
    1. gorilla本來就寫爛?
    2. 這份example的作者call gorilla api的方式錯誤(使用邏輯不對 or 參數傳錯...etc)

經過一些測試以後發現第一種可能性較高，因為經過debug之後發現問題出在`server.go: FinishRegistration()`，這個函式來自於deprecated repo，所以migrate到新的repo或許就能解決問題

一些測試的截圖
![](https://i.imgur.com/cjgU1iJ.png)

![](https://i.imgur.com/9mHOLN3.png)

---

# 0502 Update

## outline
1. new repo(w/ firebase)
2. GO migration

### New repo
[TypeScript WebAuthn + firebase repo](https://github.com/google/webauthndemo)
[Demo website](https://try-webauthn.appspot.com/)
在Webauthn.io網站上找到這份Google寫的repo，demo website在跑的過程都沒問題。它利用google登入，每個信箱可以註冊一把鑰匙
(目前還沒在local將整份project跑起來、也還沒仔細trace code)



### GO migration
有將所有的第三方package都升級到最新版本，但升級後連register都失敗(輸入完username後一按下register按鈕就報錯)

不過有從新版library(go-webauthn)的某串issue那邊找到了一份新的example(樣式相同、運行邏輯大致相同、寫法架構大致相同)
[issue](https://github.com/go-webauthn/webauthn/issues/58)
[New repo](https://github.com/NHAS/webauthn-example)

![](https://i.imgur.com/gUF0TTJ.png)

寫比較 - trace code(為什麼他的可以動?為什麼我們上個版本不能動?go-mod/go-sum的問題?)

差異:
1. server.go 拆成 main.go & session.go
2. webauthn.io沒用到
3. go.mod/go.sum

#### server.go(舊repo) 改名為 main.go(新repo)(簡)
`main()`的相異之處有2個:
1. 在新的example中，沒有初始化DB也沒有`session.Newstore()`
![](https://i.imgur.com/HlA3FLG.png)
2. 新的example使用Go standard lib `net/http`去handle function
![](https://i.imgur.com/OI5hWU5.png)

    而舊的example使用第三方package `gorilla/mux`
![](https://i.imgur.com/ABBm1ST.png)

相似的地方:
1. `BeginRegistration, FinishRegistration, BeginLogin, FinishLogin`
上面這四個function的內部流程一樣，只不過在新的example中有些步驟是使用standard lib而不是像舊example那樣使用第三方package。
使用std lib可以避免第三方package出包的問題

2. 至於`jsonResponse()`的實作則是完全一樣




#### session.go(吳)

session definition: 
Internet session is a connection between a client and a server computer. It is essential for exchange of information between two computers.

StartSession:
```go
func (db *sessiondb) StartSession(data *webauthn.SessionData) string {

	db.mu.Lock()
	defer db.mu.Unlock()

	sessionId, _ := random(32)
	db.sessions[sessionId] = data

	return sessionId
}
```
- 生成一個新的sessionID給用戶，使用自己定義的random function去生成長度為32個字母的string。"_"代表不回傳任何東西。

GetSession:
```go
func (db *sessiondb) GetSession(sessionID string) (*webauthn.SessionData, error) {

	db.mu.Lock()
	defer db.mu.Unlock()

	session, ok := db.sessions[sessionID]
	if !ok {
		return nil, fmt.Errorf("error getting session '%s': does not exist", sessionID)
	}

	return session, nil
}
```
- 使用mutex的技巧讓一次只能有一個goroutine進入db.sessions，然後開始找尋傳入的sessionID在session map裡面有沒有對應的session object。如果session object不存在就會產生錯誤訊息。

- defer是蠻特殊的語法，寫在defer後方的function會等到附近的function都return之後才會開始執行。這個例子來說，會先return session and nil之後才執行db.mu.Unlock()，這是用來確保資源有正確被釋放掉。

在main function裡面，**StartSession**是用在BeginRegistration跟BeginLogin的SetCookie標準函式庫裡面，有稍微查了一下Cookie，他是讓伺服器可以保存某個HTTP的狀態，那狀態就要用SetCookie去設定。該作者表示如果駭客把使用者登入狀態的SID查出來，就可以用這個SID去登入帳號，所以如果要加強安全性的話，可以多加一些屬性(attribute)進去SetCookie函數裡面，目前這份repo使用的屬性舊只有簡單的Name、Value跟Path，所以要增加安全性的話可以多想幾個屬性。

```go
http.SetCookie(w, &http.Cookie{
		Name:  "registration",
		Value: sessionDb.StartSession(sessionData),
		Path:  "/",
	})
```

**GetSession**跟**DeleteSession**是用在FinishRegistration還有FinishLogin。

---

#### webauthn.io沒用到(楊)
為什麼沒用到?被甚麼取代了?
觀察到原本寫在session.go require那邊的webauthn.io消失了。

#### go.mod/go.sum(祝)
1.少了甚麼?多了甚麼?
![](https://i.imgur.com/PlkZnyQ.png)

2. go.mod/go.sum

go.mod是用來管理第三方套件，類似flutter 中 pubspec.yaml中，管理module dependnecy的部分。

利用這些指令來管理module之間的dependency。

go.sum存的是checksum，主要是確保我們跑別人的repo時的環境一致，同時也避免我們在使用第三方repo時，過程中被其他人竄改的問題。

以下是 go mod 相關的指令，可以使用在command中輸入go mod help來查看。
![](https://i.imgur.com/su5FYMo.png)

從這可以看到之前在嘗試將使用舊版library的修改新版的...
![](https://i.imgur.com/h6Va8CD.png)


[Byexample, G. (2020, November 5). Understanding go.sum and go.mod file in Go. Golangbyexample.](https://golangbyexample.com/go-mod-sum-module/) 
[Chang, E. (2019, January 5). Go Modules 三兩事 Medium. Hieven.](https://hieven.medium.com/go-modules-%E4%B8%89%E5%85%A9%E4%BA%8B-cd5964f7c50)
## Milestone(6月)
FIDO2接上token server，再能夠接到firebase

---
# 0509 Update

## outline
1. 看能不能把後端獨立出來接上app(吳)
2. 仔細trace go library(go-webauthn)(簡)
3. 看go語言能不能像typescript那份一樣跟firebase連結(楊)

### 1. 後端獨立出來接上app
目標:
嘗試把之前寫好的flutter前端註冊、登入按鈕成功連上Go server。

問題: 
1. GO需不需要打包成甚麼文件放到flutter?
    - Go並不需要打包成額外的文件傳給flutter，只要flutter送出http請求後，Go有接收到就可以完成實作。

2. 假如用手機app的介面，按下register或者login會跑到一個網頁來驗證嗎?
    - flutter APP可以經由webpage API打開網頁，經由設定成相同的網址(是不是網址不確定、也還不確定webview_flutter.dart的原理)，可以讓註冊與登入兩個button再按下時打開瀏覽器、並且在瀏覽器那邊做GO的FIDO2 webauth。

3. 流程
    - 註冊
    ```mermaid
    flowchart TD;
    手機APP前端的FIDO註冊按鈕 --> 
    FIDO的註冊功能 --> 
    GO成功註冊 --> 
    手機頁面跳出註冊成功;
    ```
    - 登入
    ```mermaid
    flowchart TD;
    手機APP前端的FIDO登入按鈕 --> 
    FIDO的登入功能 --> 
    C[GO成功登入\n產生Token & 傳到前端] -->
    A[firebase的CustomSignIn\n驗證token] -->
    手機頁面跳出登入成功;
    ```

reference:
[flutter为什么不用Go语言，而用Dart?](https://www.zhihu.com/question/355433789)
[Go-flutter安裝](https://zhuanlan.zhihu.com/p/254728424)
[完整流程 Flutter 集成 Golang 多语言跨端开发基础案例](https://blog.csdn.net/weixin_42795002/article/details/125322338)
[dart front end, Go back end](https://dev.to/codefuture/flutter-dart-frontend-golang-backend-api-4320)
[open a web page in flutter application](https://stackoverflow.com/questions/66347863/is-possible-open-a-web-page-in-a-flutter-app)

### 2. trace go library(go-webauthn)
總共有3個子資料夾`metadata, protocol, webauthn`
1. metadata: 定義struct, const。ex. 定義有哪些verification method
![](https://i.imgur.com/KJwsbtp.png)

2. protocol
    authenticator, base64encode, challenge, credential, client...等Go file
但也有一些東西不知道它的用意為何ex. attestation.go

    在子資料夾protocol/webauthncose中看到
`VerifySignature()`、定義了哪些signature algo以及它如何定義struct去存public key的資訊
![](https://i.imgur.com/Bb0l2XD.png)

3. webauthn
const.go: 定義timeout時長
login.go: BeginLogin, FinishLogin, ValidateLogin...等function

    registration.go: BeginRegistration, FinishRegistration...等function
    
    types.go: 定義webauthn configuration(RPID, RPDisplayName, RPOrigins...)、User、SessionData有哪些attributes
    user.go: 實作在types.go定義的User interface

在Go example裡，只要在session.go處理好sessionData與在user.go處理好credential，在main.go中只需簡單呼叫BeginRegistration~FinishLogin就可以實作出整個流程

額外補充:
[CBOR & COSE](https://www.iana.org/assignments/cose/cose.xhtml#algorithms)
[CBOR wiki](https://en.wikipedia.org/wiki/CBOR)
CBOR = Concise Binary Object Representation
COSE = CBOR Object Signing and Encryption

### 3. Go連上firebase可行性
想法: 在GO這邊經由API轉換(用json做出JWT)，然後用JWT以custom token的方式傳給firebase

結合上述想法需要使用的技術細節:
- 0317更新的流程圖(現在GO接上firebase在流程的哪邊)
![](https://i.imgur.com/Iv0oPFS.png =40%x)
- 0418更新的JWT-GO package可以用來轉換JWT
![](https://i.imgur.com/1XesK9L.png)
- 0329更新的firebase.signInWithCustomToken
![](https://i.imgur.com/tZHxjpv.png)

需要做的步驟
1. 尋找適合切入、新增function的地方(目前猜測是finishLogin那邊、或是main也可能可以)
2. 使用html測試
    a. 測試方法: 將JWT字串印出到terminal之類的
    b. 驗證字串正確性...? 不知道該如何驗證做出來的字串是否正確(寫一份C code來算出答案?)需要實作自己的keylist?(這部分還需要調查)
5. 若測試成功，嘗試將html前端的部分移除，並且接到flutter(本次outline-1報告的內容)

### 建議
1. 前端後端各自跑在兩個裝置(機器)上，藉由http溝通(不需要將GO包到APP中)
2. 也許還是要包一個後端的framework(打某個網址就執行某個function call)
3. 概念上就是"兩個網站如何溝通"
4. 學長的影片vol.07/vol.13可以看一下

---

# 0516 Update

## outline
0. 看影片7,13(each member)
1. 試試看實作Go JWT的部分(專指產生Token的部分)
2. web嵌入的方式調查(如何嵌入?)
3. 評估是不是有辦法用原生的方式做出simple-demo內做的事情

### webauthn如何放到架構內，讓前端能以http來使用(楊)
//週二的時候一起寫comment，所以周二前要看完影片
其實課程上的東西跟我們之前調查過的資訊沒有太大的落差
需要使用http來getToken
![](https://hackmd.io/_uploads/r15vOhlr3.png)
我們在影片中看到get, post, delete的功能(用途)
![](https://hackmd.io/_uploads/rJ2XfTxr2.png)
![](https://i.imgur.com/V3PquRl.png)

### 試試看實作JWT的部分(專指產生Token的部分)(簡)
[tutorial-1](https://juejin.cn/post/7219651766706159653)
[tutorial-2](https://super-buaa-2021.github.io/GinBook/post-basis/p8-jwt-go-use.html)
[tutorial-3?](https://docs.google.com/document/d/1jA-xj1oGwRrj4AqaY3_Ekz8rS2QWGTtcK5PopOZsECw/edit?usp=sharing)
按照tutorial-1 example code去產生jwt後，再拿到[jwt.io](https://jwt.io/)上驗證內容與正確性，結果沒有問題
底下舉HMAC+SHA256為例
![](https://hackmd.io/_uploads/SJcIL-ZSh.png)
![](https://hackmd.io/_uploads/SkbOIWZB2.png)
![](https://hackmd.io/_uploads/HJV5I-ZSn.png)

### web嵌入的方式調查(如何嵌入?)(吳)

目前想法：在flutter app加一個按鈕連到html的網站，接著產生token到firebase驗證，最後再跳回app。

- 流程
    ```mermaid
    flowchart TD;
    app設置跳轉按鈕 --> 
    跳到網頁的註冊/登入畫面 -->
    FIDO註冊 -->
    註冊成功 -->
    手機頁面跳出註冊成功;
    跳到網頁的註冊/登入畫面 --> 
    C[GO成功登入\n產生Token & 傳到前端] -->
    A[firebase的CustomSignIn\n驗證token] -->
    手機頁面跳出登入成功;
    ```

[open a web page in flutter application](https://stackoverflow.com/questions/66347863/is-possible-open-a-web-page-in-a-flutter-app)，
網址: 10.0.2.2.8080(= localhost)變成一個自創網址

基本上只需要將Go project成功部署到google cloud [佈署教學](https://cloud.google.com/go/getting-started/#:~:text=Run%20your%20app%20Build%20the%20app%2C%20which%20automatically,opens%20a%20new%20window%20with%20your%20running%20app.)
剩下就import webview_flutter.dart
使用它的API就可以了
這個API能夠在手機應用程式上開啟瀏覽器
[webview_flutter.dart demo on github](https://github.com/pjbelo/flutter_webview_demo)

要先小規模測試？
[Part #1 - Building a Simple Go Web App from Scratch.](https://medium.com/google-cloud/building-a-go-web-app-from-scratch-to-deploying-on-google-cloud-part-1-building-a-simple-go-aee452a2e654)
[Part #2 — Deploying our Go App on Google App Engine (GAE).](https://medium.com/google-cloud/building-a-go-web-app-from-scratch-to-deploying-on-google-cloud-part-2-deploying-our-go-app-on-a07285dfa6a9)
[Bonus - Quickstart: Google Cloud Environment Building](https://cloud.google.com/appengine/docs/flexible/go/create-app)

經過評估，我們跑測試時的吞吐量應該會在免費的範圍內。
計費標準：200萬http requests/month
### 評估是不是有辦法用原生的方式做出simple-demo內做的事情(祝)

![](https://hackmd.io/_uploads/rkCvxt7r3.png)
[Flutter介紹：取得外部資料 - networking](https://ithelp.ithome.com.tw/articles/10300015)
[How to develop a platform channel in Flutter between Dart and Native Code](https://medium.com/47billion/creating-a-bridge-in-flutter-between-dart-and-native-code-in-java-or-objectivec-5f80fd0cd713)
* Server side
[~~HttpRequest class~~](https://api.flutter.dev/flutter/dart-io/HttpRequest-class.html)

## 建議
1. 原生的方式比較好(往這個方向調查)
2. 考量要不要移除嵌入的網頁
3. 那GO該怎麼接到flutter? flutter-GO? GO如何傳http request?

---

# 0523 Update

## outline
1. Flutter介紹：取得外部資料 - networking
2. How to develop a platform channel in Flutter between Dart and Native Code

### Flutter如何取得外部資料 - networking(祝、楊)
[official package guide](https://pub.dev/packages/http)
[official package repo](https://github.com/dart-lang/http)
可以從html sample那邊的function開始想我們最後會需要做哪些事情，再來找flutter有沒有對應的東西
- get
範例:
```code=
Future<http.Response> fetchAlbum() {
  return http.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));
}
```
- get-response
範例:
```code=
Future<Album> fetchAlbum() async {
  final response = await http
      .get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return Album.fromJson(jsonDecode(response.body));
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}
```
- post
```code=
Future<http.Response> createAlbum(String title) {
  return http.post(
    Uri.parse('https://jsonplaceholder.typicode.com/albums'),
    headers: <String, String>{
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode(<String, String>{
      'title': title,
    }),
  );
}
```
- post-response
```code=
Future<Album> createAlbum(String title) async {
  final response = await http.post(
    Uri.parse('https://jsonplaceholder.typicode.com/albums'),
    headers: <String, String>{
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode(<String, String>{
      'title': title,
    }),
  );

  if (response.statusCode == 201) {
    // If the server did return a 201 CREATED response,
    // then parse the JSON.
    return Album.fromJson(jsonDecode(response.body));
  } else {
    // If the server did not return a 201 CREATED response,
    // then throw an exception.
    throw Exception('Failed to create album.');
  }
}
```
trace過官方repo之後，大概可以了解到他們是怎麼實作出http request的
1. encode, decode
2. mock, stub(for test)
3. send bytestream out
4. call close!

至於更細、到更底層的部分，就沒有在這個repo裡面看到了(bytestream最後會怎麼處理?)
註: 使用http package要注意版本問題(因為最新版的更新時間是約莫18個小時前)

reference:
[1][Fetch data from the internet](https://docs.flutter.dev/cookbook/networking/fetch-data)
[2][Send data to the internet](https://docs.flutter.dev/cookbook/networking/send-data)


### How to develop a platform channel in Flutter between Dart and Native Code(簡、吳)

Flutter提供了很多XXXChannel Class讓我們可以進行跨平台溝通像是`MethodChannel, EventChannel, BasicMessageChannel`...等，這邊主要介紹MethodChannel的用法。

找到2個flutter官方寫的範例，都有platform_channels的範例code可以測試跨平台。
1. [flutter samples(github)](https://github.com/flutter/samples)
這個repo platform channel的範例比較完整，用實體手機測試沒有問題

    ![](https://hackmd.io/_uploads/SJ3wNS9Sn.png)
    (上圖為flutter，下圖為kotlin)![](https://hackmd.io/_uploads/r1uLBrqBh.png)
    有3點要注意
    1. method channel name在flutter, native端要一樣。
    2. invokeMethod的第一個參數是methodName，
    在native端可利用MethodCall Class中的`method`屬性存取
    3. 第二個參數是arguments(必須以map的方式傳入)。在native端可利用MethodCall Class中的`argument(String key)`函式存取
    
    在native端會用到[io.flutter.plugin.common](https://api.flutter.dev/javadoc/io/flutter/plugin/common/package-summary.html)這個套件，裡面定義了MethodChannel, [MethodCall](https://api.flutter.dev/javadoc/io/flutter/plugin/common/MethodCall.html)...等

2. [flutter examples(github)](https://github.com/flutter/flutter/tree/master/examples)
[官網教學](https://docs.flutter.dev/platform-integration/platform-channels?tab=android-channel-java-tab)
    dart:
    ```javascript
    class _MyHomePageState extends State<MyHomePage> {
      static const platform = MethodChannel('samples.flutter.dev/battery');
    ```

    ```javascript
    // in dart file
    String _batteryLevel = 'Unknown battery level.';

    Future<void> _getBatteryLevel() async {
      String batteryLevel;
      try {
        final int result = await platform.invokeMethod('getBatteryLevel'); // method name
        batteryLevel = 'Battery level at $result % .';
      } on PlatformException catch (e) {
        batteryLevel = "Failed to get battery level: '${e.message}'.";
      }

      setState(() {
        _batteryLevel = batteryLevel;
      });
    }
    ```

    kotlin:
    ```kotlin=
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
          // This method is invoked on the main thread.
          call, result ->
          if (call.method == "getBatteryLevel") { // the same method name as in dart file
            val batteryLevel = getBatteryLevel()

            if (batteryLevel != -1) {
              result.success(batteryLevel)
            } else {
              result.error("UNAVAILABLE", "Battery level not available.", null)
            }
          } else {
            result.notImplemented()
          }
        }
    ```
    Android battery APIs 會在 getBatteryLevel()裡面實作(line 5)。

    這個battery api如何找? 
    <img src="https://hackmd.io/_uploads/BkcsAcsS3.png" alt="Image" style="border: 2px solid #000000;max-width: 120%; max-height: 170%;">

    [官網](https://developer.android.com/reference/android/os/BatteryManager?hl=en#getIntProperty(int))就可以找到資料，以後要實做到的public key也可以透過官網就查到api。[public key](https://developer.android.com/reference/java/security/PublicKey?hl=en)

ref:
[flutter services package - invokeMethod()](https://api.flutter.dev/flutter/services/MethodChannel/invokeMethod.html)
[Flutter - Dart API docs](https://api.flutter.dev/)
[Flutter platform integration APIs for Android](https://api.flutter.dev/javadoc/)
[Flutter platform integration APIs for iOS](https://api.flutter.dev/objcdoc/)

## 建議
1. http request更底層不用trace太深(學長建議說會用就好)
2. public key是藉由軟體算出來的嗎?還是藉由安全晶片做出來的?
3. trace kotlin's public key?
4. 其他人怎麼做加解密?
5. IOS & Android會需要分別實作(原生)?

## 調整meeting時間
下禮拜照常meeting，從???開始，改成兩個禮拜meeting一次
至於會持續多久? 未定

最後決定下周(6/1)meeting，之後改兩個禮拜一次

---

# 0530 Update

還是一起做吧~
## outline
1. 調查一下public key
2. 加解密project
3. IOS & Android method channel

### Public Key
1. public key是藉由軟體算出來的嗎?還是藉由安全晶片做出來的?
找到的資料顯示kotlin的public key是從java.secure.PublicKey來的。
而java的實作方式超級簡單，因此也看不出是否是使用軟體計算還是安全晶片計算。
![](https://hackmd.io/_uploads/rJKUV7QI2.png)
要深入知道algorithm的話，就要看到KeyPair那邊
結論是這個結果是藉由軟體算出來的(至少RSA是)
[source code](https://github.com/frohoff/jdk8u-jdk/tree/master/src/share/classes/java/security)

2. Java實作keypair

```java=
package org.kodejava.security;

import java.security.*;
import java.util.Base64;

public class GenerateKeyPairDemo {
    public static void main(String[] args) {
        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");

            // Initialize KeyPairGenerator.
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
            keyGen.initialize(1024, random);

            // Generate Key Pairs, a private key and a public key.
            KeyPair keyPair = keyGen.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey publicKey = keyPair.getPublic();

            Base64.Encoder encoder = Base64.getEncoder();
            System.out.println("privateKey: " + encoder.encodeToString(privateKey.getEncoded()));
            System.out.println("publicKey: " + encoder.encodeToString(publicKey.getEncoded()));
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
            e.printStackTrace();
        }
    }
}
```
這個簡短的code是在說明如何用一個字串生成出他的public跟private key。
先選擇要加密的字串以及要用的演算法 --> 生成隨機亂數 --> 產生keypair

```java=
   public PrivateKey readPemRsaPrivateKey(String pemFilename) throws
            java.io.IOException,
            java.security.NoSuchAlgorithmException,
            java.security.spec.InvalidKeySpecException
    {
            String pemString = File2String(pemFilename);

            pemString = pemString.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
            pemString = pemString.replace("-----END RSA PRIVATE KEY-----", "");

            byte[] decoded = Base64.decodeBase64(pemString);

            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
            KeyFactory kf = KeyFactory.getInstance("RSA");

            return kf.generatePrivate(keySpec);
    }
```

bing版本:
```java=
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;

public class KeyPairGeneratorExample {
    public static void main(String[] args) throws Exception {
        // Creating KeyPair generator object
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");

        // Initializing the KeyPairGenerator
        keyPairGen.initialize(2048);

        // Generate the pair of keys
        KeyPair pair = keyPairGen.generateKeyPair();

        // Getting the private key from the pair
        PrivateKey privKey = pair.getPrivate();

        // Getting the public key from the pair
        PublicKey publicKey = pair.getPublic();
    }
}
```

也有看到有人是用command line在實作keypair，不確定那樣做的用意。

ref: 
[public/private key implementation using java - 1](https://stackoverflow.com/questions/8434428/get-public-key-from-private-in-java)
[public/private key implementation using java - 2](https://stackoverflow.com/questions/11410770/load-rsa-public-key-from-file)

### 加解密project(楊、祝)
沒有找到其他跟我們想法類似、想使用上周說到的東西來做
那別人怎麼做的?
直接使用flutter已經有的security package(幾周前有介紹過)
[和主題無關但可能有用](https://github.com/CoderJava/flutter_to_native)

### IOS & Android會需要分別實作(原生)?(簡)
video: [Flutter Call Native Code | Android & iOS](https://www.youtube.com/watch?v=6UftAAKSuVs)
上次報告時學長有提到flutter platform channel的報告內容跟認知的似乎不太一樣，但後來去看影片後覺得講的是一樣的東西，只不過這邊只說明了method channel的用法，而沒有提及event channel怎麼使用，沒有像影片那樣提及較多東西

我也回顧了一下上禮拜platform channel example的那兩個repo source code，發現它們在原生端處理method channel的地方都一樣
(都在`configureFlutterEngine()`裡)，寫法也大同小異

kotlin:
```kotlin
class MainActivity : FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        MethodChannel(flutterEngine.dartExecutor, "methodChannelDemo")
                .setMethodCallHandler { call, result ->
                    // logic here
                }
```

java:
```java
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
  new MethodChannel(flutterEngine.getDartExecutor(), BATTERY_CHANNEL).setMethodCallHandler(
      new MethodCallHandler() {
        @Override
        public void onMethodCall(MethodCall call, Result result) {
            //logic here
        }
      }
  );
```

影片中的這兩張圖片簡單地說明了兩個channel的差別與運作原理
![](https://hackmd.io/_uploads/rJCOnxTr2.png)

![](https://hackmd.io/_uploads/Sku8plpHn.png)

最後影片中也有提到[pigeon package](https://pub.dev/packages/pigeon)可幫我們自動生成native code，可以讓整個過程更快、更簡單也確保了type-safe

## 建議
1. 原生的code -> 讓flutter能夠抓到 -> 透過methodChannel來call native -> call 安全晶片API
2. Android安全晶片API(native)
3. 關鍵字"硬體加解密", "android native", "android調用硬體"

---

# 0620 Update

## outline
1. flutter接到GO project
2. 佈署GO到google cloud
3. android native研究

### 佈署GO到google cloud(楊)
佈署的GO版本是能夠產生JWT的版本
Go project github: [github links](https://github.com/System-Integration-Implementation/JWT-Demo)
可以直接demo(using Google Cloud Shell)

### flutter接到GO project(誰有時間就先寫)
// 先軟體模擬加密
flutter-Go API送request給google cloud ->
用寫在Go project的生物辨識認證 ->
go project return JWT
有JWT之後 -> 送給firebase customSignIn

- 主要功能(FIDO)
難點:
    - 不確定以現在的方式需要改多少比例的GO project以讓他成功被呼叫
        - main function那邊(main需要留多少)
        - 呼叫function(因為目前demo的版本是用給定的user直接做出來 也就是作假解的意思)
    - 不確定原理
        - 最主要是不確定是不是需要另行手動turn on server?
        - 還是單純部署上去就可以了?(像是firebase一樣)
        - 也不確定部署了之後是隨時都會開著server嗎?
        - 還是有rerquest時才會重新啟動?
        
    總之現在進度: 成功部署到Google Cloud，但目前覺得需要再更改過go裡面的code才能動。
    流程: 先把盡量把流程圖裡面可能會使用到的function都生出來，之後再組裝。
- UI
- 主要是參考之前找到的go example 將login 的版面配置進行調整。

![](https://hackmd.io/_uploads/By-VPjWO2.gif "title" =216x456)

- 改變版面配置。

| Public Polls                                                   | Private Polls                                                  |                          Create Polls                          |
| -------------------------------------------------------------- | -------------------------------------------------------------- |:--------------------------------------------------------------:|
| ![](https://hackmd.io/_uploads/rJ-VYoZun.png "title" =216x456) | ![](https://hackmd.io/_uploads/BJZVtobd3.png "title" =216x456) | ![](https://hackmd.io/_uploads/H1ZEKsbdn.png "title" =216x456) |










### android native研究


目標: 希望直接call到安全晶片

關鍵字"硬體加解密", "硬體生成keypair", "安全晶片生成keypair", "android調用安全晶片"

還是沒有查到直接調用安全晶片的方式，幾乎查什麼都會帶我們到android developers的網站，看蠻多影片教學也都直接呼叫api。

問題: 
-    希望是用很常見的RSA、AES嗎，還是要自己想一種演算法?
-    還是不太理解直接call安全晶片是什麼意思。

參考資料:

[加解密影片教學](https://www.bing.com/videos/search?q=android+hardware+encryption&docid=603495587189435719&mid=7B21651C9119652189E67B21651C9119652189E6&view=detail&FORM=VIRE)(還有很多，但這個感覺最詳細)

## 建議


---