Compare commits

..

111 Commits

Author SHA1 Message Date
cab2843706
chore(release): publish packages
All checks were successful
continuous-integration/drone/push Build is passing
- native_crypto@0.2.0
 - native_crypto_example@0.0.1
2023-04-05 17:11:43 +02:00
3cab93ff71
chore(release): publish packages
All checks were successful
continuous-integration/drone/push Build is passing
- native_crypto_android@0.1.2
 - native_crypto_ios@0.1.2
 - native_crypto_platform_interface@0.2.0
2023-04-05 17:07:07 +02:00
c98b9947b4
docs: update readmes/licences
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-05 17:02:38 +02:00
01832a3b03
chore(api): file format + update readme file 2023-04-05 16:46:35 +02:00
7dc07c693a
feat(api): update example for ios file encryption 2023-04-05 16:42:16 +02:00
550fe8b73e
refactor(ios): remove useless lines/classes 2023-04-05 16:41:54 +02:00
7c8f7206f0
feat(api): update example with benchmark + file encryption 2023-04-05 15:17:56 +02:00
0bf72447a0
fix(android): file encryption 2023-04-05 15:16:45 +02:00
108c394a25
test(api): update mocks with new interface 2023-04-04 23:24:20 +02:00
e47004e2d0
feat(api): update example 2023-04-04 23:23:47 +02:00
2f22cc549d
fix(api): accept empty decrypted plaintext 2023-04-04 23:22:43 +02:00
5be6296829
fix(ios): key length in bits 2023-04-04 23:21:39 +02:00
68217ac4b9
feat(ios): use swift pigeon generator 2023-04-04 22:37:12 +02:00
560f5b4942
feat(android): use kotlin pigeon generator 2023-04-04 22:36:50 +02:00
f570ed076a
feat(interface)!: set pigeon as default implementation 2023-04-04 22:36:10 +02:00
c8ff1149d7
feat(api)!: rework full api with better object oriented architecture 2023-02-22 20:16:40 +01:00
8044ccfa43
feat(interface): make api injectable for test 2023-02-22 20:13:51 +01:00
d8cf8dddc4
feat(android): generate pigeon messages 2023-02-22 17:31:58 +01:00
ccb51adbc4
feat(ios): generate pigeon messages 2023-02-22 17:31:12 +01:00
0a040d2971
feat(interface)!: add pigeon + add hmac + remove useless decryption method 2023-02-22 17:27:58 +01:00
ff981b2361
docs: add android/ios development instructions 2023-02-22 17:25:58 +01:00
f47c352efb
docs: add uml models 2023-02-22 17:25:20 +01:00
38cb0a5988
build: add vscode settings 2023-02-22 17:24:46 +01:00
39badb5613
chore(interface): update deps
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 17:07:36 +01:00
3b03e05efe
ci: update drone, melos and pre-commit config 2023-01-07 17:05:06 +01:00
8f4041d7bf Merge pull request 'chore(deps): update dependency flutter_lints to v2' (#5) from renovate/flutter_lints-2.x into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #5
2022-06-01 14:21:03 +00:00
Renovate
897b97f5d5 chore(deps): update dependency flutter_lints to v2
All checks were successful
continuous-integration/drone/pr Build is passing
2022-06-01 14:11:26 +00:00
bee0b3e38e Merge pull request 'Fix/Update' (#1) from Fix/Update into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #1
2022-06-01 11:51:15 +00:00
4fde7d0aa2
ci: add badge
All checks were successful
continuous-integration/drone/pr Build is passing
2022-06-01 13:47:38 +02:00
d28a49a67b
docs: update readme
All checks were successful
continuous-integration/drone Build is passing
2022-06-01 12:21:49 +02:00
cf4227fb58
ci: add drone config file 2022-05-27 18:18:58 +02:00
ac35cd89ca
style: format all + melos test command 2022-05-27 17:34:53 +02:00
1b00d20ec5
fix: update code to pass tests 2022-05-27 16:41:43 +02:00
cefa73ec3d
test: add cipher tests 2022-05-27 16:41:25 +02:00
ebdcf00c15
fix: update code to pass all tests 2022-05-26 23:23:13 +02:00
96f9aad1b3
test: (WIP) add some tests 2022-05-26 23:22:14 +02:00
c5d42feef4
feat(api): add exception code for platform throw 2022-05-26 20:43:43 +02:00
48ebabb54c
feat: rework bytearray and memory optimization, simplify API 2022-05-26 20:42:53 +02:00
6939a8df7e
refactor: (WIP) optimize exceptions and bytearray 2022-05-26 16:26:16 +02:00
9bfe969c7d
test: (WIP) add mocks and tests for secret key 2022-05-26 16:25:35 +02:00
81335dc350
test(platform): add tests for platform and method channel 2022-05-25 23:31:01 +02:00
9aa4eeb567
fix: update verify function 2022-05-25 23:30:13 +02:00
e016d640c4
doc: copy readme 2022-05-25 23:29:13 +02:00
39a0a44730
fix: change tag length in aes gcm cipher 2022-05-25 23:29:02 +02:00
5729fff09b
refactor(example): update benchmark page 2022-05-25 23:27:22 +02:00
f592799970
docs: update readme 2022-05-25 21:33:51 +02:00
ff6af2491a
chore(release): publish packages
- native_crypto@0.1.1
2022-05-25 16:26:10 +02:00
ee79b8d20f
chore(release): publish packages
- native_crypto_ios@0.1.1
 - native_crypto_android@0.1.1
 - native_crypto_platform_interface@0.1.1
2022-05-25 16:23:41 +02:00
0bb6aa4b78
fix: benchmark output 2022-05-25 15:43:51 +02:00
2ed8aab69f
perf(ios): optimize swift code 2022-05-25 15:43:12 +02:00
142dd17ad2
refactor(ios): rework swift part 2022-05-25 15:42:56 +02:00
a1112b5c80
feat: export new exceptions 2022-05-25 10:51:20 +02:00
a7affea1e1
perf: x10 perfomance improvement on android with better list management 2022-05-24 23:59:10 +02:00
6397e10c05
feat(example): add PointyCastle benchmark 2022-05-24 18:43:46 +02:00
41354e3dc4
refactor(android): clean and modernize kotlin code 2022-05-24 18:43:14 +02:00
2fe4172131
docs: add link to readme file 2022-05-23 23:15:00 +02:00
70a6fda3ed
refactor: change file organization 2022-05-23 23:11:04 +02:00
32106f549f
fix: update and fix code 2022-05-23 21:54:48 +02:00
51f6e6aa24
style(platform): reformat code 2022-05-23 21:54:16 +02:00
2559112beb
docs: add some resources 2022-05-23 21:53:08 +02:00
7c1208156e
chore: update entire repo 2022-05-23 21:24:27 +02:00
7fc1ef5968 Add all 2022-01-14 19:12:42 +01:00
8cd192c6b0 Add native examples 2021-12-28 18:20:06 +01:00
41b59b2b93 Investigate in slow data transferts 2021-12-28 17:10:18 +01:00
3381ff67b9 Add new public api and example 2021-12-28 16:03:50 +01:00
c01e0a12ba Add android implementation 2021-12-28 16:03:07 +01:00
9b66f2044a Update license, and readme 2021-12-28 16:02:55 +01:00
9e0d921564 Switch to Federated Plugin layout 2021-12-27 21:13:26 +01:00
9790be4a5c Update readme 2021-05-08 20:21:43 +02:00
be3ed99379 Update exemple app 2021-05-08 20:11:45 +02:00
871e3b74ed Add RSA keys generation 2021-05-08 20:11:28 +02:00
36e942f41e Rework key size 2021-05-08 20:10:49 +02:00
9160338e7a Remove some AES modes 2021-05-08 20:10:19 +02:00
501e5bcf08 Remove old API 2021-02-16 22:08:40 +01:00
9daa2f129e Update pubspec, changelog and license 2021-02-16 22:08:29 +01:00
8a40df7543 Add csv log in benchmark page + new sizes 2021-02-16 21:48:45 +01:00
189d31cf02 Fix cipher page example with the new cipherText class 2021-02-16 21:47:53 +01:00
d6f398af40 Change some outputs 2021-02-16 21:42:06 +01:00
5da95a0c39 Fix OutOfMemoryError on large files 2021-02-16 21:41:30 +01:00
4d0dd7e5e3 Fix readme 2020-12-20 22:21:24 +01:00
e32c54d685 Update example app with full tests 2020-12-20 22:20:22 +01:00
a77ef8df00 Fix digest on iOS 2020-12-20 22:07:24 +01:00
5404bd5ba8 Update readme 2020-12-19 23:24:56 +01:00
8a076b5148 Fix readme 2020-12-19 23:11:06 +01:00
aa3e364d3f Update readme 2020-12-19 23:07:49 +01:00
f402e8bdf9 Clean swift plugin main file 2020-12-19 21:45:56 +01:00
9007fded56 Add cipher class and cipher algorithm in swift 2020-12-19 21:45:34 +01:00
5545badfc5 Add keyderivation with pbkdf2 in swift 2020-12-19 21:45:03 +01:00
447d6b2c5a Add hash and digest in swift 2020-12-19 21:44:44 +01:00
1e360f16fe Add KeyDerivation implementation in swift 2020-12-19 21:44:31 +01:00
a5d3b76b01 Fix sha enums 2020-12-19 21:42:36 +01:00
43de719ea6 Expose API 2020-12-19 17:24:55 +01:00
a5e42970ce Add callList invoke and catch all platform exceptions 2020-12-19 17:24:41 +01:00
efcf21ebc8 Add some exceptions 2020-12-19 17:24:10 +01:00
e4fa93a775 Add async "constructors" for key generation 2020-12-19 17:23:52 +01:00
acc9261a66 Rename Paddin to PlainTextPadding 2020-12-19 17:21:01 +01:00
06bb6e1595 Update exemple app 2020-12-19 17:19:56 +01:00
11d43fe64c Update kotlin specific code 2020-12-19 17:19:32 +01:00
4d84a938ac Update platform with algo enums and digest 2020-12-18 13:52:30 +01:00
20d58e1bfd Add key derivation interface and pbkdf2 implementation 2020-12-18 13:52:05 +01:00
9c3e6c3d33 Add hash function implementation 2020-12-18 13:51:45 +01:00
f117c8c4c2 Add enum for algorithms and parameters names 2020-12-18 13:51:10 +01:00
281f36894f Add RSA KEM implementation 2020-12-17 22:11:20 +01:00
6ba8da275d Add Key Encapsulation Mechanism (KEM) interface 2020-12-17 22:11:03 +01:00
51d10362e9 Add AES cipher implementation 2020-12-17 22:10:27 +01:00
98c0dce1de Add new platform layer 2020-12-17 22:09:55 +01:00
286818d108 Add keyspecs interface and implementation 2020-12-17 22:09:27 +01:00
2e240e5072 Add some exceptions 2020-12-17 22:09:00 +01:00
3066b56450 Add cipher related interfaces 2020-12-17 22:08:42 +01:00
aaa68278d2 Add key interface and implementation 2020-12-17 22:08:21 +01:00
356e95e70a Remove some useless statements and switches 2020-12-17 22:07:35 +01:00
294 changed files with 13265 additions and 1886 deletions

20
.drone.yml Normal file
View File

@ -0,0 +1,20 @@
kind: pipeline
type: docker
name: default
steps:
- name: quality-check
image: git.wyatt-studio.fr/wyatt-foss/flutter-melos:2.9.0
commands:
- melos run quality-check
- melos run publish:validate
- name: publish
image: git.wyatt-studio.fr/wyatt-foss/flutter-melos:2.9.0
commands:
- melos run publish:validate
trigger:
branch:
- master
event:
- push

468
.gitignore vendored
View File

@ -1,107 +1,7 @@
# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig # File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig
# Created by https://www.gitignore.io/api/windows,visualstudiocode,android,androidstudio,cocoapods,dart,flutter,intellij+all,kotlin,macos,swift,xcode,xcodeinjection # Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,dart,flutter,java,jetbrains+all,kotlin,linux,objective-c,rust,swift,windows,xcode
# Edit at https://www.gitignore.io/?templates=windows,visualstudiocode,android,androidstudio,cocoapods,dart,flutter,intellij+all,kotlin,macos,swift,xcode,xcodeinjection # Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,macos,dart,flutter,java,jetbrains+all,kotlin,linux,objective-c,rust,swift,windows,xcode
### Android ###
# Built application files
*.apk
*.ap_
*.aab
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
release/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# IntelliJ
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
# Android Studio 3 in .gitignore file.
.idea/caches
.idea/modules.xml
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
.idea/navEditor.xml
# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
#*.keystore
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
# Google Services (e.g. APIs or Firebase)
# google-services.json
# Freeline
freeline.py
freeline/
freeline_project_description.json
# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md
# Version control
vcs.xml
# lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/
### Android Patch ###
gen-external-apklibs
output.json
# Replacement of .externalNativeBuild directories introduced
# with Android Studio 3.5.
.cxx/
### CocoaPods ###
## CocoaPods GitIgnore Template
# CocoaPods - Only use to conserve bandwidth / Save time on Pushing
# - Also handy if you have a large number of dependant pods
# - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE
Pods/
### Dart ### ### Dart ###
# See https://www.dartlang.org/guides/libraries/private-files # See https://www.dartlang.org/guides/libraries/private-files
@ -109,6 +9,7 @@ Pods/
# Files and directories created by pub # Files and directories created by pub
.dart_tool/ .dart_tool/
.packages .packages
build/
# If you're building an application, you may want to check-in your pubspec.lock # If you're building an application, you may want to check-in your pubspec.lock
pubspec.lock pubspec.lock
@ -116,6 +17,9 @@ pubspec.lock
# If you don't generate documentation locally you can remove this line. # If you don't generate documentation locally you can remove this line.
doc/api/ doc/api/
# dotenv environment variables file
.env*
# Avoid committing generated Javascript files: # Avoid committing generated Javascript files:
*.dart.js *.dart.js
*.info.json # Produced by the --dump-info flag. *.info.json # Produced by the --dump-info flag.
@ -125,13 +29,25 @@ doc/api/
*.js.deps *.js.deps
*.js.map *.js.map
.flutter-plugins
.flutter-plugins-dependencies
### Dart Patch ###
# dotenv environment variables file
.env
### Flutter ### ### Flutter ###
# Flutter/Dart/Pub related # Flutter/Dart/Pub related
**/doc/api/ **/doc/api/
.flutter-plugins .fvm/
.flutter-plugins-dependencies
.pub-cache/ .pub-cache/
.pub/ .pub/
coverage/
lib/generated_plugin_registrant.dart
# For library packages, dont commit the pubspec.lock file.
# Regenerating the pubspec.lock file lets you test your package against the latest compatible versions of its dependencies.
# See https://dart.dev/guides/libraries/private-files#pubspeclock
#pubspec.lock
# Android related # Android related
**/android/**/gradle-wrapper.jar **/android/**/gradle-wrapper.jar
@ -139,6 +55,7 @@ doc/api/
**/android/captures/ **/android/captures/
**/android/gradlew **/android/gradlew
**/android/gradlew.bat **/android/gradlew.bat
**/android/key.properties
**/android/local.properties **/android/local.properties
**/android/**/GeneratedPluginRegistrant.java **/android/**/GeneratedPluginRegistrant.java
@ -159,12 +76,15 @@ doc/api/
**/ios/**/profile **/ios/**/profile
**/ios/**/xcuserdata **/ios/**/xcuserdata
**/ios/.generated/ **/ios/.generated/
**/ios/Flutter/.last_build_id
**/ios/Flutter/App.framework **/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework **/ios/Flutter/Flutter.framework
**/ios/Flutter/Flutter.podspec
**/ios/Flutter/Generated.xcconfig **/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx **/ios/Flutter/app.flx
**/ios/Flutter/app.zip **/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/ **/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json **/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.* **/ios/Runner/GeneratedPluginRegistrant.*
@ -175,8 +95,34 @@ doc/api/
!**/ios/**/default.perspectivev3 !**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
### Intellij+all ### ### Java ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
### JetBrains+all ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff # User-specific stuff
@ -186,6 +132,9 @@ doc/api/
.idea/**/dictionaries .idea/**/dictionaries
.idea/**/shelf .idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files # Generated files
.idea/**/contentModel.xml .idea/**/contentModel.xml
@ -206,6 +155,9 @@ doc/api/
# When using Gradle or Maven with auto-import, you should exclude module files, # When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using # since they will be recreated, and may cause churn. Uncomment if using
# auto-import. # auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml # .idea/modules.xml
# .idea/*.iml # .idea/*.iml
# .idea/modules # .idea/modules
@ -222,6 +174,7 @@ cmake-build-*/
*.iws *.iws
# IntelliJ # IntelliJ
out/
# mpeltonen/sbt-idea plugin # mpeltonen/sbt-idea plugin
.idea_modules/ .idea_modules/
@ -232,6 +185,9 @@ atlassian-ide-plugin.xml
# Cursive Clojure plugin # Cursive Clojure plugin
.idea/replstate.xml .idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ) # Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml com_crashlytics_export_strings.xml
crashlytics.properties crashlytics.properties
@ -244,20 +200,14 @@ fabric.properties
# Android studio 3.1+ serialized cache file # Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser .idea/caches/build_file_checksums.ser
### Intellij+all Patch ### ### JetBrains+all Patch ###
# Ignores the whole .idea folder and all .iml files # Ignore everything but code style settings and run configurations
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 # that are supposed to be shared within teams.
.idea/ .idea/*
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 !.idea/codeStyles
!.idea/runConfigurations
modules.xml
.idea/misc.xml
*.ipr
# Sonarlint plugin
.idea/sonarlint
### Kotlin ### ### Kotlin ###
# Compiled class file # Compiled class file
@ -265,22 +215,27 @@ modules.xml
# Log file # Log file
# BlueJ files # BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME) # Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files # # Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ### ### macOS ###
# General # General
@ -291,6 +246,7 @@ hs_err_pid*
# Icon must end with two \r # Icon must end with two \r
Icon Icon
# Thumbnails # Thumbnails
._* ._*
@ -310,15 +266,25 @@ Network Trash Folder
Temporary Items Temporary Items
.apdisk .apdisk
### Swift ### ### macOS Patch ###
# iCloud generated files
*.icloud
### Objective-C ###
# Xcode # Xcode
# #
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated ## User settings
DerivedData/ xcuserdata/
## Various settings ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout
## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
DerivedData/
*.moved-aside
*.pbxuser *.pbxuser
!default.pbxuser !default.pbxuser
*.mode1v3 *.mode1v3
@ -327,32 +293,15 @@ DerivedData/
!default.mode2v3 !default.mode2v3
*.perspectivev3 *.perspectivev3
!default.perspectivev3 !default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint
## Obj-C/Swift specific ## Obj-C/Swift specific
*.hmap *.hmap
## App packaging
*.ipa *.ipa
*.dSYM.zip *.dSYM.zip
*.dSYM *.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
.build/
# Add this line if you want to avoid checking in Xcode SPM integration.
# .swiftpm/xcode
# CocoaPods # CocoaPods
# We recommend against adding the Pods directory to your .gitignore. However # We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at: # you should judge for yourself, the pros and cons are mentioned at:
@ -365,19 +314,18 @@ playground.xcworkspace
# Add this line if you want to avoid checking in source code from Carthage dependencies. # Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts # Carthage/Checkouts
Carthage/Build Carthage/Build/
# Accio dependency management
Dependencies/
.accio/
# fastlane # fastlane
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the # It is recommended to not store the screenshots in the git repo.
# screenshots whenever they are needed. # Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit: # For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control # https://docs.fastlane.tools/best-practices/source-control/#source-control
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png fastlane/screenshots/**/*.png
fastlane/test_output
# Code Injection # Code Injection
# After new code Injection tools there's a generated folder /iOSInjectionProject # After new code Injection tools there's a generated folder /iOSInjectionProject
@ -385,17 +333,102 @@ fastlane/screenshots/**/*.png
iOSInjectionProject/ iOSInjectionProject/
### Objective-C Patch ###
### Rust ###
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
### Swift ###
# Xcode
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm
.build/
# CocoaPods
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
# Pods/
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace
# Carthage
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
# Accio dependency management
Dependencies/
.accio/
# fastlane
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
# Code Injection
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
### VisualStudioCode ### ### VisualStudioCode ###
.vscode
.vscode/* .vscode/*
!.vscode/settings.json !.vscode/settings.json
!.vscode/tasks.json !.vscode/tasks.json
!.vscode/launch.json !.vscode/launch.json
!.vscode/extensions.json !.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ### ### VisualStudioCode Patch ###
# Ignore all local history of files # Ignore all local history of files
.history .history
.ionide
# Support for Project snippet scope
.vscode/*.code-snippets
# Ignore code-workspaces
*.code-workspace
### Windows ### ### Windows ###
# Windows thumbnail cache files # Windows thumbnail cache files
@ -424,121 +457,26 @@ $RECYCLE.BIN/
*.lnk *.lnk
### Xcode ### ### Xcode ###
# Xcode
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## User settings ## Xcode 8 and earlier
## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) ### Xcode Patch ###
## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
## Xcode Patch
*.xcodeproj/* *.xcodeproj/*
!*.xcodeproj/project.pbxproj !*.xcodeproj/project.pbxproj
!*.xcodeproj/xcshareddata/ !*.xcodeproj/xcshareddata/
!*.xcworkspace/contents.xcworkspacedata !*.xcworkspace/contents.xcworkspacedata
/*.gcno /*.gcno
### Xcode Patch ###
**/xcshareddata/WorkspaceSettings.xcsettings **/xcshareddata/WorkspaceSettings.xcsettings
### XcodeInjection ### # End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,dart,flutter,java,jetbrains+all,kotlin,linux,objective-c,rust,swift,windows,xcode
# Code Injection
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
### AndroidStudio ###
# Covers files to be ignored for android development using Android Studio.
# Built application files
# Files for the ART/Dalvik VM
# Java class files
# Generated files
# Gradle files
.gradle
# Signing files
.signing/
# Local configuration file (sdk path, etc)
# Proguard folder generated by Eclipse
# Log Files
# Android Studio
/*/build/
/*/local.properties
/*/out
/*/*/build
/*/*/production
*~
*.swp
# Android Patch
# External native build folder generated in Android Studio 2.2 and later
# NDK
obj/
# IntelliJ IDEA
/out/
# User-specific configurations
.idea/caches/
.idea/libraries/
.idea/shelf/
.idea/.name
.idea/compiler.xml
.idea/copyright/profiles_settings.xml
.idea/encodings.xml
.idea/scopes/scope_settings.xml
.idea/vcs.xml
.idea/jsLibraryMappings.xml
.idea/datasources.xml
.idea/dataSources.ids
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml
# OS-specific files
.DS_Store?
# Legacy Eclipse project files
.classpath
.project
.cproject
.settings/
# Mobile Tools for Java (J2ME)
# Package Files #
# virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml)
## Plugin-specific files:
# mpeltonen/sbt-idea plugin
# JIRA plugin
# Mongo Explorer plugin
.idea/mongoSettings.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
### AndroidStudio Patch ###
!/gradle/wrapper/gradle-wrapper.jar
# End of https://www.gitignore.io/api/windows,visualstudiocode,android,androidstudio,cocoapods,dart,flutter,intellij+all,kotlin,macos,swift,xcode,xcodeinjection
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
# IntelliJ
*.iml
*.ipr
*.iws
.idea/
# Mac
.DS_Store

7
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,7 @@
repos:
- repo: https://github.com/compilerla/conventional-pre-commit
rev: v2.1.1
hooks:
- id: conventional-pre-commit
stages: [commit-msg]
args: [build, ci, docs, feat, fix, perf, refactor, style, test, chore]

28
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,28 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "native_crypto",
"cwd": "packages/native_crypto/example",
"request": "launch",
"type": "dart"
},
{
"name": "native_crypto (profile mode)",
"cwd": "packages/native_crypto/example",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "native_crypto (release mode)",
"cwd": "packages/native_crypto/example",
"request": "launch",
"type": "dart",
"flutterMode": "release"
},
]
}

19
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,19 @@
{
"bloc.newCubitTemplate.type": "equatable",
"psi-header.config": {
"blankLinesAfter": 0,
"forceToTop": true,
},
"psi-header.templates": [
{
"language": "*",
"template": [
"Copyright 2019-<<year>> <<author>>",
"",
"Use of this source code is governed by an MIT-style",
"license that can be found in the LICENSE file or at",
"https://opensource.org/licenses/MIT.",
]
}
],
}

6
AUTHORS Normal file
View File

@ -0,0 +1,6 @@
# Below is a list of people and organizations that have contributed
# to this project. Names should be added to the list like so:
#
# Name/Organization <email address>
Hugo Pointcheval <git@pcl.ovh>

View File

@ -1,3 +1,157 @@
## 0.0.1 # Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## 2023-04-05
### Changes
---
Packages with breaking changes:
- [`native_crypto` - `v0.2.0`](#native_crypto---v020)
Packages with other changes:
- [`native_crypto_example` - `v0.0.1`](#native_crypto_example---v001)
---
#### `native_crypto` - `v0.2.0`
- **REFACTOR**: (WIP) optimize exceptions and bytearray.
- **REFACTOR**: update benchmark page.
- **FIX**: accept empty decrypted plaintext.
- **FIX**: update code to pass tests.
- **FIX**: update code to pass all tests.
- **FIX**: change tag length in aes gcm cipher.
- **FEAT**: update example for ios file encryption.
- **FEAT**: update example with benchmark + file encryption.
- **FEAT**: update example.
- **FEAT**: rework bytearray and memory optimization, simplify API.
- **DOCS**: update readmes/licences.
- **DOCS**: update readme.
- **BREAKING** **FEAT**: rework full api with better object oriented architecture.
#### `native_crypto_example` - `v0.0.1`
- **REFACTOR**: update benchmark page.
- **REFACTOR**: change file organization.
- **PERF**: x10 perfomance improvement on android with better list management.
- **FIX**: update code to pass all tests.
- **FIX**: benchmark output.
- **FIX**: update and fix code.
- **FEAT**: update example for ios file encryption.
- **FEAT**: update example with benchmark + file encryption.
- **FEAT**: update example.
- **FEAT**: rework bytearray and memory optimization, simplify API.
- **FEAT**: export new exceptions.
- **FEAT**: add PointyCastle benchmark.
## 2023-04-05
### Changes
---
Packages with breaking changes:
- [`native_crypto_platform_interface` - `v0.2.0`](#native_crypto_platform_interface---v020)
Packages with other changes:
- [`native_crypto_android` - `v0.1.2`](#native_crypto_android---v012)
- [`native_crypto_ios` - `v0.1.2`](#native_crypto_ios---v012)
---
#### `native_crypto_platform_interface` - `v0.2.0`
- **REFACTOR**: (WIP) optimize exceptions and bytearray.
- **FIX**: update verify function.
- **FEAT**: make api injectable for test.
- **FEAT**: add exception code for platform throw.
- **DOCS**: update readmes/licences.
- **BREAKING** **FEAT**: set pigeon as default implementation.
- **BREAKING** **FEAT**: add pigeon + add hmac + remove useless decryption method.
#### `native_crypto_android` - `v0.1.2`
- **FIX**: file encryption.
- **FEAT**: use kotlin pigeon generator.
- **FEAT**: generate pigeon messages.
- **DOCS**: update readmes/licences.
#### `native_crypto_ios` - `v0.1.2`
- **REFACTOR**: remove useless lines/classes.
- **FIX**: key length in bits.
- **FEAT**: use swift pigeon generator.
- **FEAT**: generate pigeon messages.
- **DOCS**: update readmes/licences.
## 2022-05-25
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`native_crypto` - `v0.1.1`](#native_crypto---v011)
---
#### `native_crypto` - `v0.1.1`
- **REFACTOR**: change file organization.
- **PERF**: x10 perfomance improvement on android with better list management.
- **FIX**: benchmark output.
- **FIX**: update and fix code.
- **FEAT**: export new exceptions.
- **FEAT**: add PointyCastle benchmark.
- **DOCS**: add link to readme file.
## 2022-05-25
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`native_crypto_ios` - `v0.1.1`](#native_crypto_ios---v011)
- [`native_crypto_android` - `v0.1.1`](#native_crypto_android---v011)
- [`native_crypto_platform_interface` - `v0.1.1`](#native_crypto_platform_interface---v011)
---
#### `native_crypto_ios` - `v0.1.1`
- **REFACTOR**: rework swift part.
- **PERF**: optimize swift code.
#### `native_crypto_android` - `v0.1.1`
- **REFACTOR**: clean and modernize kotlin code.
- **PERF**: x10 perfomance improvement on android with better list management.
- **FEAT**: export new exceptions.
#### `native_crypto_platform_interface` - `v0.1.1`
- **PERF**: x10 perfomance improvement on android with better list management.
- **FEAT**: export new exceptions.
* TODO: Describe initial release.

View File

@ -1,8 +1,6 @@
native_crypto
MIT License MIT License
Copyright (c) 2020 Hugo Pointcheval Copyright (c) 2020-2023 Hugo Pointcheval
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

319
README.md
View File

@ -1,155 +1,280 @@
# NativeCrypto <p align="center">
<img width="700px" src="resources/native_crypto.png" style="background-color: rgb(255, 255, 255)">
<h5 align="center">Fast and powerful cryptographic functions for Flutter.</h5>
</p>
![native_crypto](/assets/native_crypto.png) <p align="center">
<a href="https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis">
<img src="https://img.shields.io/badge/Style-Wyatt%20Analysis-blue.svg?style=flat-square" alt="Style: Wyatt Analysis" />
</a>
Fast crypto functions for Flutter. <a href="https://github.com/invertase/melos">
<img src="https://img.shields.io/badge/Maintained%20with-melos-f700ff.svg?style=flat-square" alt="Maintained with Melos" />
</a>
* Table of content <a href="https://drone.wyatt-studio.fr/hugo/native-crypto">
* [Background](#background) <img src="https://drone.wyatt-studio.fr/api/badges/hugo/native-crypto/status.svg" alt="Build Status" />
* [Performances](#performances) </a>
* [Installation](#installation) </p>
* [Usage](#usage)
* [Example](#example)
* [How](#how)
* [Todo](#todo)
## Background ---
🤔 Why I started this project ? [[Changelog]](./CHANGELOG.md) | [[License]](./LICENSE)
Because I faced a performance issue when I was using **PointyCastle**.
It's quite simple, judge for yourself, these are times for AES256 encryption on an Android device (**Huawei P30 Pro**). ---
| Size | PointyCastle | ## About
|------|--------------|
| 100 kB | 190 ms
| 200 kB | 314 ms
| 300 kB | 1138 ms
| 400 kB | 2781 ms
| 500 kB | 4691 ms
| 600 kB | 7225 ms
| 700 kB | 10264 ms
| 800 kB | 13582 ms
| 900 kB | 17607 ms
> We notice that these times, in addition to being far too big, are **not even linear**. The goal of this plugin is to provide a fast and powerful cryptographic functions by calling native libraries. On Android, it uses [javax.cypto](https://developer.android.com/reference/javax/crypto/package-summary), and on iOS, it uses [CommonCrypto](https://opensource.apple.com/source/CommonCrypto/) and [CryptoKit](https://developer.apple.com/documentation/cryptokit/)
## Performances I started this projet because I wanted to add cryptographic functions on a Flutter app. But I faced a problem with the well-known [Pointy Castle](https://pub.dev/packages/pointycastle) library: the performance was very poor. Here some benchmarks and comparison:
⏱ On an **Android 10** device: **Huawei P30 Pro** ![](resources/benchmarks.png)
| Size | NativeCrypto | For comparison, on a *iPhone 13*, you can encrypt/decrypt a message of **2MiB** in **~5.6s** with PointyCastle and in **~40ms** with NativeCrypto. And on an *OnePlus 5*, you can encrypt/decrypt a message of **50MiB** in **~6min30** with PointyCastle and in less than **~1s** with NativeCrypto.
|------|--------------|
| 1 mB | 27 ms
| 2 mB | 43 ms
| 3 mB | 78 ms
| 4 mB | 93 ms
| 5 mB | 100 ms
| 10 mB | 229 ms
| 50 mB | 779 ms
## Installation In short, NativeCrypto is incomparable with PointyCastle.
🚧 You can easely setup a Flutter project with this plugin. ## Features
Just add these lines in your **pubspec.yaml**: * Hash functions
- SHA-256
- SHA-384
- SHA-512
* HMAC functions
- HMAC-SHA-256
- HMAC-SHA-384
- HMAC-SHA-512
* Secure random
* PBKDF2
* AES
- Uint8List encryption/decryption
- File encryption/decryption
```yaml ## Quick start
native_crypto:
git:
url: https://gogs.pointcheval.fr/hugo/native-crypto-flutter.git
ref: v0.0.x
```
> Replace "x" with the current version!
Then in your code:
```dart ```dart
// Symmetric crypto. import 'package:native_crypto/native_crypto.dart';
import 'package:native_crypto/symmetric_crypto.dart';
// To handle exceptions. Future<void> main() async {
import 'package:native_crypto/exceptions.dart'; // Message to encrypt
final Uint8List message = 'Hello World!'.toBytes();
// Ask user for a password
final String password = await getPassword();
// Initialize a PBKDF2 object
final Pbkdf2 pbkdf2 = Pbkdf2(
length: 32, // 32 bytes
iterations: 1000,
salt: 'salt'.toBytes(),
hashAlgorithm: HashAlgorithm.sha256,
);
// Derive a secret key from the password
final SecretKey secretKey = await pbkdf2(password: password);
// Initialize an AES cipher
final AES cipher = AES(
key: secretKey,
mode: AESMode.gcm,
padding: AESPadding.none,
);
// Encrypt the message
final CipherText<AESCipherChunk> cipherText = await cipher.encrypt(message);
// Decrypt the message
final Uint8List decryptedMessage = await cipher.decrypt(cipherText);
// Verify and print the decrypted message
assert(listEquals(message, decryptedMessage));
print(decryptedMessage.toStr());
}
``` ```
Check the [example](./native_crypto/example) for a complete example.
Please take a look a the compatibility table below to check if your target is supported.
> Note: This **Flutter** example must run on a real device or a simulator.
## Usage ## Usage
To create an AES instance, and generate a key. #### Compatibility
```dart First, check compatibility with your targets.
AES aes = AES();
await aes.init(KeySize.bits256) | iOS | Android | MacOS | Linux | Windows | Web |
| --- | ------- | ----- | ----- | ------- | --- |
| ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
> Warning: NativeCrypto 0.2.0+ is not compatible with lower NativeCrypto versions. Especially, with NativeCrypto 0.0. X because the cipher mode is not the same. Now, NativeCrypto uses AES-GCM mode instead of AES-CBC mode. (See [Changelog](./CHANGELOG.md))
NativeCrypto ciphertexts are formatted as follow:
```
+------------------+--------------------+------------------+
| Nonce (12 bytes) | Cipher text (n-28) | Tag (16 bytes) |
+------------------+--------------------+------------------+
``` ```
You can also generate key, then use it in AES. > Warning: If your data comes from another source, make sur to use the same format.
#### Hash
To digest a message, you'll need to initialize a Hasher object implementing `Hash` . Then, you can digest your message.
```dart ```dart
Uint8List aeskey = await KeyGenerator().secretKey(keySize: KeySize.bits256); Hash hasher = Sha256();
AES aes = AES(key: aeskey); Uint8List digest = await hasher.digest(message);
``` ```
You can create a key with PBKDF2. > In NativeCrypto, you can use the following hash functions: SHA-256, SHA-384, SHA-512
#### HMAC
To generate a HMAC, you'll need to initialize a `Hmac` object. Then, you can generate a HMAC from a message and a secret key.
```dart ```dart
Uint8List key = await KeyGenerator().pbkdf2(password, salt, keyLength: 32, iteration: 10000, digest: Digest.sha256); Hmac hmac = HmacSha256();
AES aes = AES(key: key); Uint8List hmac = await hmac.digest(message, secretKey);
``` ```
Then you can encrypt/decrypt data with this instance. > In NativeCrypto, you can use the following HMAC functions: HMAC-SHA-256, HMAC-SHA-384, HMAC-SHA-512
#### Keys
You can build a `SecretKey` from utf8, utf16, base64, base16 (hex) strings, int list or raw bytes. You can also generate a SecretKey from secure random.
```dart ```dart
encryptedPayload = await aes.encrypt(data); SecretKey secretKey = SecretKey(bytes); // bytes is a Uint8List
decryptedPayload = await aes.decrypt(encryptedPayload); SecretKey secretKey = SecretKey.fromUtf8('secret');
SecretKet secretKey = SecretKey.fromUtf16('secret');
SecretKey secretKey = SecretKey.fromBase64('c2VjcmV0');
SecretKey secretKey = SecretKey.fromBase16('63657274');
SecretKey secretKey = SecretKey.fromList([0x73, 0x65, 0x63, 0x72, 0x65, 0x74]);
SecretKey secretKey = await SecretKey.fromSecureRandom(32); // 32 bytes
``` ```
Or you can also use AES on the fly with different keys. #### Key derivation
You can derive a `SecretKey` using **PBKDF2**.
First, you need to initialize a `Pbkdf2` object.
```dart ```dart
Uint8List aeskey = await KeyGenerator().secretKey(keySize: KeySize.bits256); final Pbkdf2 pbkdf2 = Pbkdf2(
encryptedPayload = await AES().encrypt(data, key: aeskey); length: 32, // 32 bytes
decryptedPayload = await AES().decrypt(encryptedPayload, key: aeskey); iterations: 1000,
salt: salt.toBytes(),
hashAlgorithm: HashAlgorithm.sha256,
);
``` ```
Available `enums` are: Then, you can derive a `SecretKey` from a password.
```dart ```dart
enum KeySize { bits128, bits192, bits256 } SecretKey secretKey = await pbkdf2(password: password);
enum Digest { sha1, sha256, sha512 }
``` ```
`KeySizes` defines all available key sizes for generation. > Note: Pbkdf2 is a callable class. You can use it like a function.
`Digest` defines all available digest for PBKDF2. #### Cipher
## Example And now, you can use the `SecretKey` to encrypt/decrypt a message.
🔍 Look in **example/lib/** for an example app. First, you need to initialize a `Cipher` object.
## How ```dart
final AES cipher = AES(
key: key,
mode: AESMode.gcm,
padding: AESPadding.none,
);
```
🔬 But how it is possible ?? Then, you can encrypt your message.
Using the native implementation of crypto libs available on each OS. ```dart
final CipherText<AESCipherChunk> cipherText = await cipher.encrypt(message);
```
For **Android**: After an encryption you obtain a `CipherText` which contains chunks. You can get the underlying bytes with `cipherText.bytes` .
* [javax.crypto](https://docs.oracle.com/javase/7/docs/api/javax/crypto/package-summary.html) Uppon receiving encrypted message `receivedData` , you can decrypt it.
* [java.security](https://docs.oracle.com/javase/7/docs/api/java/security/package-summary.html) You have to reconstruct the ciphertext and the setup the chunk factory.
For **iOS**: ```dart
final CipherText<AESCipherChunk> receivedCipherText CipherText(
receivedData,
chunkFactory: (bytes) => AESCipherChunk(
bytes,
ivLength: cipher.mode.ivLength,
tagLength: cipher.mode.tagLength,
),
),
```
* [CommonCrypto](https://developer.apple.com/library/archive/documentation/Security/Conceptual/cryptoservices/Introduction/Introduction.html) Then, you can decrypt your message.
## Todos ```dart
Uint8List message = await cipher.decrypt(receivedCipherText);
```
🚀 You can contribute to this project. #### Files
* [x] Implement working cross platform AES encryption/decryption. You can encrypt/decrypt files.
* [x] Different key sizes support.
* [x] Improve performances. First, you need to initialize a `Cipher` object.
* [x] Add exceptions.
* [x] PBKDF2 support. ```dart
* [ ] Add other ciphers. final AES cipher = AES(
* [ ] Clean platform specific code. key: key,
* [ ] Add asym crypto support... mode: AESMode.gcm,
padding: AESPadding.none,
);
```
Then, you can encrypt your file.
```dart
await cipher.encryptFile(plainText, cipherText);
```
> Note: `plainText` and `cipherText` are `File` objects.
You can decrypt your file.
```dart
await cipher.decryptFile(cipherText, plainText);
```
#### Advanced
You can force the use of a specific IV. Please note that the IV must be unique for each encryption.
```dart
final CipherText<AESCipherChunk> cipherText = await cipher.encryptWithIV(message, iv);
```
⚠️ Use `encrypt(...)` instead of `encryptWithIV(...)` if you don't know what you are doing.
## Development
### Android
> https://docs.flutter.dev/development/packages-and-plugins/developing-packages#step-2b-add-android-platform-code-ktjava
* Launch Android Studio.
* Select Open an existing Android Studio Project in the Welcome to Android Studio dialog, or select File > Open from the menu, and select the `packages/native_crypto/example/android/build.gradle` file.
* In the Gradle Sync dialog, select OK.
* In the Android Gradle Plugin Update dialog, select Dont remind me again for this project.
### iOS
> https://docs.flutter.dev/development/packages-and-plugins/developing-packages#step-2c-add-ios-platform-code-swifthm
* Launch Xcode.
* Select File > Open, and select the `packages/native_crypto/example/ios/Runner.xcworkspace` file.

View File

@ -1,4 +0,0 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

View File

@ -1 +0,0 @@
rootProject.name = 'native_crypto'

View File

@ -1,172 +0,0 @@
/*
* Copyright (c) 2020
* Author: Hugo Pointcheval
*/
package fr.pointcheval.native_crypto
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.Registrar
import java.security.MessageDigest
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.PBEKeySpec
import javax.crypto.spec.SecretKeySpec
/** NativeCryptoPlugin */
public class NativeCryptoPlugin : FlutterPlugin, MethodCallHandler {
// CRYPTO CONSTS
private val HASH_FUNC = "SHA-256"
private val SYM_CRYPTO_METHOD = "AES"
private val SYM_CRYPTO_PADDING = "AES/CBC/PKCS5PADDING"
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
val channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "native.crypto.helper")
channel.setMethodCallHandler(NativeCryptoPlugin());
}
companion object {
@JvmStatic
fun registerWith(registrar: Registrar) {
val channel = MethodChannel(registrar.messenger(), "native.crypto.helper")
channel.setMethodCallHandler(NativeCryptoPlugin())
}
}
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
if (call.method == "pbkdf2") {
val password = call.argument<String>("password")
val salt = call.argument<String>("salt")
val keyLength = call.argument<Int>("keyLength")
val iteration = call.argument<Int>("iteration")
val algorithm = call.argument<String>("algorithm")
val key = pbkdf2(password!!, salt!!, keyLength!!, iteration!!, algorithm!!)
if (key.isNotEmpty()) {
result.success(key)
} else {
result.error("PBKDF2ERROR", "PBKDF2 KEY IS NULL.", null)
}
} else if (call.method == "symKeygen") {
val keySize = call.argument<Int>("size") // 128, 192, 256
val aesKey = symKeygen(keySize!!) // Collection<ByteArray>
if (aesKey.isNotEmpty()) {
result.success(aesKey)
} else {
result.error("SYMKEYGENERROR", "GENERATED KEY IS NULL.", null)
}
} else if (call.method == "symEncrypt") {
val payload = call.argument<ByteArray>("payload") // ByteArray
val aesKey = call.argument<ByteArray>("aesKey") // ByteArray
val encryptedPayload = symEncrypt(payload!!, aesKey!!) // Collection<ByteArray>
if (encryptedPayload.isNotEmpty()) {
result.success(encryptedPayload)
} else {
result.error("ENCRYPTIONERROR", "ENCRYPTED PAYLOAD IS NULL.", null)
}
} else if (call.method == "symDecrypt") {
val payload = call.argument<Collection<ByteArray>>("payload") // Collection<ByteArray>
val aesKey = call.argument<ByteArray>("aesKey") // ByteArray
var decryptedPayload : ByteArray? = null
try {
decryptedPayload = symDecrypt(payload!!, aesKey!!)
if (decryptedPayload != null && decryptedPayload.isNotEmpty()) {
result.success(decryptedPayload)
} else {
result.error("DECRYPTIONERROR", "DECRYPTED PAYLOAD IS NULL. MAYBE VERIFICATION MAC IS UNVALID.", null)
}
} catch (e : Exception) {
result.error("DECRYPTIONERROR", "AN ERROR OCCURED WHILE DECRYPTING.", null)
}
} else {
result.notImplemented()
}
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
}
// CRYPTO NATIVE FUNCTIONS
private fun digest(obj: ByteArray?): ByteArray {
val md = MessageDigest.getInstance(HASH_FUNC)
return md.digest(obj)
}
private fun pbkdf2(password : String, salt : String, keyLength : Int, iteration : Int, algorithm : String) : ByteArray {
val chars: CharArray = password.toCharArray()
val spec = PBEKeySpec(chars, salt.toByteArray(), iteration, keyLength * 8)
val skf: SecretKeyFactory = if (algorithm == "sha1") {
SecretKeyFactory.getInstance("PBKDF2withHmacSHA1")
} else if (algorithm == "sha256") {
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
} else {
SecretKeyFactory.getInstance("PBKDF2withHmacSHA512")
}
return skf.generateSecret(spec).encoded
}
private fun symKeygen(keySize : Int): ByteArray {
val SYM_CRYPTO_BITS = keySize
val secureRandom = SecureRandom()
val keyGenerator = KeyGenerator.getInstance(SYM_CRYPTO_METHOD)
keyGenerator?.init(SYM_CRYPTO_BITS, secureRandom)
val skey = keyGenerator?.generateKey()
return skey!!.encoded
}
private fun symEncrypt(payload: ByteArray, aesKey: ByteArray): Collection<ByteArray> {
val mac = digest(aesKey + payload)
val key: SecretKey = SecretKeySpec(aesKey, SYM_CRYPTO_METHOD)
val cipher = Cipher.getInstance(SYM_CRYPTO_PADDING)
cipher.init(Cipher.ENCRYPT_MODE, key)
val encryptedBytes = cipher.doFinal(mac + payload)
val iv = cipher.iv
return listOf(encryptedBytes, iv);
}
private fun symDecrypt(payload: Collection<ByteArray>, aesKey: ByteArray): ByteArray? {
val key: SecretKey = SecretKeySpec(aesKey, SYM_CRYPTO_METHOD)
val cipher = Cipher.getInstance(SYM_CRYPTO_PADDING);
val iv = payload.last();
val ivSpec = IvParameterSpec(iv)
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
val decryptedBytes = cipher.doFinal(payload.first());
val mac = decryptedBytes.copyOfRange(0, 32)
val decryptedContent = decryptedBytes.copyOfRange(32, decryptedBytes.size)
val verificationMac = digest(aesKey + decryptedContent)
if (mac.contentEquals(verificationMac)) return decryptedContent
return null;
}
}

View File

@ -1,7 +0,0 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java

View File

@ -1,12 +0,0 @@
package fr.pointcheval.native_crypto_example
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
</resources>

View File

@ -1,15 +0,0 @@
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}

View File

@ -1,2 +0,0 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -1,2 +0,0 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View File

@ -1,90 +0,0 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
end
generated_key_values = {}
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) do |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
generated_key_values[podname] = podpath
else
puts "Invalid plugin specification: #{line}"
end
end
generated_key_values
end
target 'Runner' do
use_frameworks!
use_modular_headers!
# Flutter Pod
copied_flutter_dir = File.join(__dir__, 'Flutter')
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
unless File.exist?(generated_xcode_build_settings_path)
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
unless File.exist?(copied_framework_path)
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
end
unless File.exist?(copied_podspec_path)
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
end
end
# Keep pod path relative so it can be checked into Podfile.lock.
pod 'Flutter', :path => 'Flutter'
# Plugin Pods
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.each do |name, path|
symlink = File.join('.symlinks', 'plugins', name)
File.symlink(path, symlink)
pod name, :path => File.join(symlink, 'ios')
end
end
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end

View File

@ -1,22 +0,0 @@
PODS:
- Flutter (1.0.0)
- native_crypto (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- native_crypto (from `.symlinks/plugins/native_crypto/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
native_crypto:
:path: ".symlinks/plugins/native_crypto/ios"
SPEC CHECKSUMS:
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
native_crypto: 33b8108e3fcc10052862b69863efc2304c59cb2f
PODFILE CHECKSUM: 1b66dae606f75376c5f2135a8290850eeb09ae83
COCOAPODS: 1.9.1

View File

@ -1 +0,0 @@
#import "GeneratedPluginRegistrant.h"

View File

@ -1,302 +0,0 @@
// Copyright (c) 2020
// Author: Hugo Pointcheval
import 'dart:developer';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:native_crypto/symmetric_crypto.dart';
import 'package:native_crypto/exceptions.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final textController = TextEditingController();
final pwdController = TextEditingController();
String _output = 'none';
String _bench;
AES aes = AES();
List<Uint8List> encryptedPayload;
Uint8List decryptedPayload;
Uint8List key;
void _generateKey() async {
// You can also generate key before creating aes object.
// Uint8List aeskey = await KeyGenerator().secretKey(keySize: KeySize.bits256);
// AES aes = AES(key: aeskey);
var output;
try {
await aes.init(KeySize.bits256);
output = 'Key generated. Length: ${aes.key.length}';
} catch (e) {
// PlatformException or KeyException, both have message property.
output = e.message;
}
setState(() {
_output = output;
});
}
void _pbkdf2() async {
final password = pwdController.text.trim();
var output;
if (password.isEmpty) {
output = 'Password is empty';
} else {
key = await KeyGenerator().pbkdf2(password, 'salt', digest: Digest.sha512);
output = 'Key successfully derived.';
}
setState(() {
_output = output;
});
}
void _encrypt() async {
final plainText = textController.text.trim();
var output;
if (plainText.isEmpty) {
output = 'Entry is empty';
} else {
var stringToBytes = TypeHelper().stringToBytes(plainText);
// You can also pass a specific key.
// encryptedPayload = await AES().encrypt(stringToBytes, key: aeskey);
encryptedPayload = await aes.encrypt(stringToBytes, key: key?? null);
output = 'String successfully encrypted.';
}
setState(() {
_output = output;
});
}
void _alter() async {
var output;
if (encryptedPayload == null || encryptedPayload[0].isEmpty) {
output = 'Encrypt before altering payload!';
} else {
// Add 1 to the first byte
encryptedPayload[0][0] += 1;
output = 'Payload altered.';
}
setState(() {
_output = output;
});
}
void _decrypt() async {
var output;
if (encryptedPayload == null || encryptedPayload[0].isEmpty) {
output = 'Encrypt before decrypting!';
} else {
// You can also pass a specific key.
// decryptedPayload = await AES().decrypt(encryptedPayload, key: aeskey);
try {
decryptedPayload = await aes.decrypt(encryptedPayload, key: key?? null);
var bytesToString = TypeHelper().bytesToString(decryptedPayload);
output = 'String successfully decrypted:\n\n$bytesToString';
} on DecryptionException catch (e) {
output = e.message;
}
}
setState(() {
_output = output;
});
}
Future<String> _benchmark(int megabytes) async {
String output;
var bigFile = Uint8List(megabytes * 1000000);
var before = DateTime.now();
var encryptedBigFile = await aes.encrypt(bigFile);
var after = DateTime.now();
var benchmark =
after.millisecondsSinceEpoch - before.millisecondsSinceEpoch;
output = '$megabytes MB\nAES Encryption: $benchmark ms\n';
before = DateTime.now();
await aes.decrypt(encryptedBigFile);
after = DateTime.now();
benchmark = after.millisecondsSinceEpoch - before.millisecondsSinceEpoch;
output += 'AES Decryption: $benchmark ms\n\n';
return output;
}
void _testPerf({int megabytes}) async {
var output = '';
if (megabytes != null) {
output = await _benchmark(megabytes);
setState(() {
_output = output;
});
} else {
setState(() {
_bench = 'Open the logcat!';
});
for (int i=1;i<=50;i+=10) {
var benchmark = await _benchmark(i);
log(benchmark, name: 'fr.pointcheval.native_crypto');
}
}
}
@override
void initState() {
// Generate AES instance on init.
_generateKey();
super.initState();
}
void dispose() {
// Clean up the controller when the widget is disposed.
textController.dispose();
pwdController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('Native Crypto'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 10, 20),
child: Center(
child: Column(
children: <Widget>[
TextField(
controller: pwdController,
decoration: InputDecoration(
hintText: 'Test password',
),
),
SizedBox(height: 20),
FlatButton(
onPressed: _pbkdf2,
color: Colors.blue,
child: Text(
'Pbkdf2',
style: TextStyle(color: Colors.white),
)),
SizedBox(height: 30),
TextField(
controller: textController,
decoration: InputDecoration(
hintText: 'Text to encrypt.',
),
),
SizedBox(height: 20),
FlatButton(
onPressed: _encrypt,
color: Colors.blue,
child: Text(
'Encrypt String',
style: TextStyle(color: Colors.white),
)),
FlatButton(
onPressed: _alter,
color: Colors.blue,
child: Text(
'Alter encrypted payload',
style: TextStyle(color: Colors.white),
)),
FlatButton(
onPressed: _decrypt,
color: Colors.blue,
child: Text(
'Decrypt String',
style: TextStyle(color: Colors.white),
)),
SizedBox(height: 20),
// Output
Text(
_output,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
FlatButton(
onPressed: () {
_testPerf(megabytes: 1);
},
color: Colors.blue,
child: Text(
'Benchmark 1 MB',
style: TextStyle(color: Colors.white),
)),
FlatButton(
onPressed: () {
_testPerf(megabytes: 10);
},
color: Colors.blue,
child: Text(
'Benchmark 10 MB',
style: TextStyle(color: Colors.white),
)),
FlatButton(
onPressed: () {
_testPerf(megabytes: 50);
},
color: Colors.blue,
child: Text(
'Benchmark 50 MB',
style: TextStyle(color: Colors.white),
)),
SizedBox(height: 20),
FlatButton(
onPressed: () {
_testPerf();
},
color: Colors.blue,
child: Text(
'Full benchmark',
style: TextStyle(color: Colors.white),
)),
(_bench != null && _bench.isNotEmpty)
? Text(_bench)
: Container(),
],
),
),
),
),
),
);
}
}
/// Contains some useful functions.
class TypeHelper {
/// Returns bytes `Uint8List` from a `String`.
Uint8List stringToBytes(String source) {
var list = source.runes.toList();
var bytes = Uint8List.fromList(list);
return bytes;
}
/// Returns a `String` from bytes `Uint8List`.
String bytesToString(Uint8List bytes) {
var string = String.fromCharCodes(bytes);
return string;
}
}

View File

@ -1,27 +0,0 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:native_crypto_example/main.dart';
void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());
// Verify that platform version is retrieved.
expect(
find.byWidgetPredicate(
(Widget widget) => widget is Text &&
widget.data.startsWith('Running on:'),
),
findsOneWidget,
);
});
}

View File

@ -1,4 +0,0 @@
#import <Flutter/Flutter.h>
@interface NativeCryptoPlugin : NSObject<FlutterPlugin>
@end

View File

@ -1,295 +0,0 @@
//
// NativeCryptoPlugin
//
// Copyright (c) 2020
// Author: Hugo Pointcheval
//
import Flutter
import UIKit
import CommonCrypto
import Security
extension FlutterStandardTypedData {
var uint8Array: Array<UInt8> {
return Array(data)
}
var int8Array: Array<Int8> {
return data.withUnsafeBytes { raw in
[Int8](raw.bindMemory(to: Int8.self))
}
}
}
@available(iOS 10.0, *)
func generateKeypair() {
var publicKeySec, privateKeySec: SecKey?
let keyattribute = [
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeySizeInBits as String : 256
] as CFDictionary
SecKeyGeneratePair(keyattribute, &publicKeySec, &privateKeySec)
}
func crypt(operation: Int, algorithm: Int, options: Int, key: Data,
initializationVector: Data, dataIn: Data) -> Data? {
return key.withUnsafeBytes { keyUnsafeRawBufferPointer in
return dataIn.withUnsafeBytes { dataInUnsafeRawBufferPointer in
return initializationVector.withUnsafeBytes { ivUnsafeRawBufferPointer in
// Give the data out some breathing room for PKCS7's padding.
let dataOutSize: Int = dataIn.count + kCCBlockSizeAES128*2
let dataOut = UnsafeMutableRawPointer.allocate(byteCount: dataOutSize,
alignment: 1)
defer { dataOut.deallocate() }
var dataOutMoved: Int = 0
let status = CCCrypt(CCOperation(operation), CCAlgorithm(algorithm),
CCOptions(options),
keyUnsafeRawBufferPointer.baseAddress, key.count,
ivUnsafeRawBufferPointer.baseAddress,
dataInUnsafeRawBufferPointer.baseAddress, dataIn.count,
dataOut, dataOutSize, &dataOutMoved)
guard status == kCCSuccess else { return nil }
return Data(bytes: dataOut, count: dataOutMoved)
}
}
}
}
func pbkdf2(hash: CCPBKDFAlgorithm, password: String, salt: String, keyByteCount: Int, rounds: Int) -> Data? {
let passwordData = password.data(using: .utf8)!
let saltData = salt.data(using: .utf8)!
var derivedKeyData = Data(repeating: 0, count: keyByteCount)
var localDerivedKeyData = derivedKeyData
let derivationStatus = derivedKeyData.withUnsafeMutableBytes { derivedKeyBytes in
saltData.withUnsafeBytes { saltBytes in
CCKeyDerivationPBKDF(
CCPBKDFAlgorithm(kCCPBKDF2),
password, passwordData.count,
saltBytes, saltData.count,
hash,
UInt32(rounds),
derivedKeyBytes, localDerivedKeyData.count)
}
}
if (derivationStatus != kCCSuccess) {
print("Error: \(derivationStatus)")
return nil;
}
return derivedKeyData
}
func pbkdf2sha512(password: String, salt: String, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash: CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512), password: password, salt: salt, keyByteCount: keyByteCount, rounds: rounds)
}
func pbkdf2sha256(password: String, salt: String, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash: CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256), password: password, salt: salt, keyByteCount: keyByteCount, rounds: rounds)
}
func pbkdf2sha1(password: String, salt: String, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash: CCPBKDFAlgorithm(kCCPRFHmacAlgSHA1), password: password, salt: salt, keyByteCount: keyByteCount, rounds: rounds)
}
func randomGenerateBytes(count: Int) -> Data? {
let bytes = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: 1)
defer { bytes.deallocate() }
let status = CCRandomGenerateBytes(bytes, count)
guard status == kCCSuccess else { return nil }
return Data(bytes: bytes, count: count)
}
extension Data {
/// Encrypts for you with all the good options turned on: CBC, an IV, PKCS7
/// padding (so your input data doesn't have to be any particular length).
/// Key can be 128, 192, or 256 bits.
/// Generates a fresh IV for you each time, and prefixes it to the
/// returned ciphertext.
func encryptAES256_CBC_PKCS7_IV(key: Data) -> Data? {
guard let iv = randomGenerateBytes(count: kCCBlockSizeAES128) else { return nil }
// No option is needed for CBC, it is on by default.
guard let ciphertext = crypt(operation: kCCEncrypt,
algorithm: kCCAlgorithmAES,
options: kCCOptionPKCS7Padding,
key: key,
initializationVector: iv,
dataIn: self) else { return nil }
return iv + ciphertext
}
/// Decrypts self, where self is the IV then the ciphertext.
/// Key can be 128/192/256 bits.
func decryptAES256_CBC_PKCS7_IV(key: Data) -> Data? {
guard count > kCCBlockSizeAES128 else { return nil }
let iv = prefix(kCCBlockSizeAES128)
let ciphertext = suffix(from: kCCBlockSizeAES128)
return crypt(operation: kCCDecrypt, algorithm: kCCAlgorithmAES,
options: kCCOptionPKCS7Padding, key: key, initializationVector: iv,
dataIn: ciphertext)
}
enum Algorithm {
case sha256
var digestLength: Int {
switch self {
case .sha256: return Int(CC_SHA256_DIGEST_LENGTH)
}
}
}
func hash(for algorithm: Algorithm) -> Data {
let hashBytes = UnsafeMutablePointer<UInt8>.allocate(capacity: algorithm.digestLength)
defer { hashBytes.deallocate() }
switch algorithm {
case .sha256:
withUnsafeBytes { (buffer) -> Void in
CC_SHA256(buffer.baseAddress!, CC_LONG(buffer.count), hashBytes)
}
}
return Data(bytes: hashBytes, count: algorithm.digestLength)
}
}
public class SwiftNativeCryptoPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "native.crypto.helper", binaryMessenger: registrar.messenger())
let instance = SwiftNativeCryptoPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "pbkdf2":
let args = call.arguments as! NSDictionary
let password = args["password"] as! String
let salt = args["salt"] as! String
let keyLength = args["keyLength"] as! NSNumber
let iteration = args["iteration"] as! NSNumber
let algo = args["algorithm"] as! String
var keyBytes: Data?
if (algo == "sha1") {
keyBytes = pbkdf2sha1(password: password, salt: salt, keyByteCount: keyLength.intValue, rounds: iteration.intValue)
} else if (algo == "sha256"){
keyBytes = pbkdf2sha256(password: password, salt: salt, keyByteCount: keyLength.intValue, rounds: iteration.intValue)
} else if (algo == "sha512"){
keyBytes = pbkdf2sha512(password: password, salt: salt, keyByteCount: keyLength.intValue, rounds: iteration.intValue)
}
if keyBytes != nil {
result(FlutterStandardTypedData.init(bytes: keyBytes!))
} else {
result(FlutterError(code: "PBKDF2ERROR",
message: "PBKDF2 KEY IS NIL.",
details: nil))
}
case "symKeygen":
let args = call.arguments as! NSDictionary
let keySize = args["size"] as! NSNumber
let keyBytes = symKeygen(keySize: keySize)
if keyBytes != nil {
result(FlutterStandardTypedData.init(bytes: keyBytes!))
} else {
result(FlutterError(code: "SYMKEYGENERROR",
message: "GENERATED KEY IS NIL.",
details: nil))
}
case "symEncrypt":
let args = call.arguments as! NSDictionary
let payload = (args["payload"] as! FlutterStandardTypedData).data
let aesKey = (args["aesKey"] as! FlutterStandardTypedData).data
let encryptedPayloadIV = symEncrypt(payload: payload, aesKey: aesKey)
result(encryptedPayloadIV)
case "symDecrypt":
let args = call.arguments as! NSDictionary
let payload = args["payload"] as! NSArray
let encrypted = (payload[0] as! FlutterStandardTypedData).data
let iv = (payload[1] as! FlutterStandardTypedData).data
let encryptedPayload = [encrypted, iv]
let aesKey = (args["aesKey"] as! FlutterStandardTypedData).data
let decryptedPayload = symDecrypt(payload: encryptedPayload, aesKey: aesKey)
if decryptedPayload != nil {
result(FlutterStandardTypedData.init(bytes: decryptedPayload!))
} else {
result(FlutterError(code: "DECRYPTIONERROR",
message: "DECRYPTED PAYLOAD IS NIL. MAYBE VERIFICATION MAC IS UNVALID.",
details: nil))
}
default: result(FlutterMethodNotImplemented)
}
}
func digest(input : Data) -> Data {
let hashed = input.hash(for: .sha256)
return hashed
}
func symKeygen(keySize : NSNumber) -> Data? {
var bytes = [Int8](repeating: 0, count: keySize.intValue / 8)
let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
if status == errSecSuccess { // Always test the status.
let keyBytes = bytes.withUnsafeBytes {return Data(Array($0))}
return keyBytes
}
return nil
}
func symEncrypt(payload : Data, aesKey : Data) -> [Data] {
let mac = digest(input: aesKey + payload)
let dataToEncrypt = mac + payload
var encrypted = dataToEncrypt.encryptAES256_CBC_PKCS7_IV(key: aesKey)!
// Create a range based on the length of data to return
let range = 0..<16
// Get a new copy of data
let iv = encrypted.subdata(in: range)
encrypted.removeSubrange(range)
return [encrypted, iv]
}
func symDecrypt(payload : [Data], aesKey : Data) -> Data? {
let encrypted = payload[1] + payload[0]
var decrypted = encrypted.decryptAES256_CBC_PKCS7_IV(key: aesKey)!
// Create a range based on the length of data to return
let range = 0..<32
// Get a new copy of data
let mac = decrypted.subdata(in: range)
decrypted.removeSubrange(range)
let verificationMac = digest(input: aesKey + decrypted)
if (mac.base64EncodedData() == verificationMac.base64EncodedData()) {
return decrypted
} else {
return nil
}
}
}

View File

@ -1,22 +0,0 @@
// Copyright (c) 2020
// Author: Hugo Pointcheval
class KeyException implements Exception {
String message;
KeyException(this.message);
}
class EncryptionException implements Exception {
String message;
EncryptionException(this.message);
}
class DecryptionException implements Exception {
String message;
DecryptionException(this.message);
}
class NotImplementedException implements Exception {
String message;
NotImplementedException(this.message);
}

View File

@ -1,88 +0,0 @@
// Copyright (c) 2020
// Author: Hugo Pointcheval
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:native_crypto/exceptions.dart';
/// [Sources]
/// Plugin class.
/// Contains raw functions and specific platform calls.
///
/// Use [symmetrical_crypto] for an **AES Layer API**.
class NativeCrypto {
/// [Private]
/// Contains the channel for platform specific code.
static const MethodChannel _channel =
const MethodChannel('native.crypto.helper');
/// PBKDF2.
///
/// [keyLength] is in Bytes.
/// It returns an `Uint8List`.
Future<Uint8List> pbkdf2(String password, String salt, {int keyLength: 32, int iteration: 10000, String algorithm: 'sha256'}) async {
Uint8List key;
try {
key = await _channel.invokeMethod('pbkdf2', <String, dynamic>{
'password': password,
'salt': salt,
'keyLength': keyLength,
'iteration': iteration,
'algorithm': algorithm,
});
} on PlatformException catch (e) {
throw e;
}
return key;
}
/// Generates AES key.
///
/// [size] is in bits, 128, 192 or 256.
/// It returns an `Uint8List`.
Future<Uint8List> symKeygen(int size) async {
Uint8List aesKey;
try {
aesKey = await _channel.invokeMethod('symKeygen', <String, dynamic>{
'size': size,
});
} on PlatformException catch (e) {
throw e;
}
return aesKey;
}
/// Encrypts passed data with a given AES key.
///
/// Generates a random **IV**. Returns a list
/// of `Uint8List` with encrypted cipher as first
/// and IV as second member.
Future<List<Uint8List>> symEncrypt(
Uint8List payloadbytes, Uint8List aesKey) async {
final List<Uint8List> encryptedPayload =
await _channel.invokeListMethod('symEncrypt', <String, dynamic>{
'payload': payloadbytes,
'aesKey': aesKey,
});
return encryptedPayload;
}
/// Decrypts a passed payload with a given AES key.
///
/// The payload must be a list of `Uint8List`
/// with encrypted cipher as first and IV as second member.
Future<Uint8List> symDecrypt(
List<Uint8List> payloadbytes, Uint8List aesKey) async {
Uint8List decryptedPayload;
try {
decryptedPayload = await _channel.invokeMethod('symDecrypt', <String, dynamic>{
'payload': payloadbytes,
'aesKey': aesKey,
});
} on PlatformException catch (e) {
throw DecryptionException(e.message);
}
return decryptedPayload;
}
}

View File

@ -1,205 +0,0 @@
// Copyright (c) 2020
// Author: Hugo Pointcheval
import 'dart:async';
import 'dart:developer';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'src/native_crypto.dart';
import 'exceptions.dart';
const String TAG_ERROR = 'error.native_crypto.symmetric_crypto';
const String TAG_DEBUG = 'debug.native_crypto.symmetric_crypto';
/// Defines all available key sizes.
enum KeySize { bits128, bits192, bits256 }
/// Defines all available digest.
enum Digest { sha1, sha256, sha512 }
/// Defines all available ciphers.
enum Cipher { AES }
/// Key Helper
///
/// You can generate Secret keys of different sizes.
class KeyGenerator {
/// Generate a secret key.
///
/// You can specify a `keySize`. Default is 256 bits.
/// It returns an `Uint8List`.
Future<Uint8List> secretKey({KeySize keySize}) async {
int size;
switch (keySize) {
case KeySize.bits128:
size = 128;
break;
case KeySize.bits192:
size = 192;
break;
case KeySize.bits256:
size = 256;
break;
default:
// Default size = 256 bits
size = 256;
break;
}
Uint8List key;
try {
key = await NativeCrypto().symKeygen(size);
log("KEY LENGTH: ${key.length}", name: TAG_DEBUG);
} on PlatformException catch (e) {
log(e.message, name: TAG_ERROR);
throw e;
}
return key;
}
/// PBKDF2.
///
/// `keyLength` is in Bytes.
/// It returns an `Uint8List`.
Future<Uint8List> pbkdf2(String password, String salt, {int keyLength: 32, int iteration: 10000, Digest digest: Digest.sha256}) async {
Uint8List key;
String algo;
if (digest == Digest.sha1) algo = 'sha1';
if (digest == Digest.sha256) algo = 'sha256';
if (digest == Digest.sha512) algo = 'sha512';
try {
key = await NativeCrypto().pbkdf2( password, salt, keyLength: keyLength, iteration: iteration, algorithm: algo);
log(key.toString());
log("PBKDF2 KEY LENGTH: ${key.length} | DIGEST: $algo", name: TAG_DEBUG);
} on PlatformException catch (e) {
log(e.message, name: TAG_ERROR);
throw e;
}
return key;
}
}
/// AES Helper
///
/// You can encrypt and decrypt data.
class AES {
Uint8List _key;
bool _isInitialized = false;
KeySize _keySize;
/// You can pass a key in constructor.
AES({Uint8List key}) {
this._key = key;
try {
this._isInitialized = _testKey();
} on KeyException catch (e) {
this._isInitialized = false;
throw e;
}
}
/// This key is used for encryption and decryption.
Uint8List get key => this._key;
/// Check if the AES object is intialized with a valid key before perform any operation.
bool get isInitialized => this._isInitialized;
/// Defines the size of the generated or passed key.
KeySize get keySize => this._keySize;
/// [Private]
/// Tests if the key is valid.
///
/// The key must be 128, 192 or 256 bits long.
bool _testKey() {
if (this.key != null) {
switch (this.key.length) {
case 16:
this._keySize = KeySize.bits128;
break;
case 24:
this._keySize = KeySize.bits192;
break;
case 32:
this._keySize = KeySize.bits256;
break;
default:
var error = 'Invalid key length: ${this.key.length} Bytes';
log(error, name: TAG_ERROR);
throw KeyException(error);
}
return true;
} else {
return false;
}
}
/// Generate an AES key.
///
/// You have to specify a `keySize`.
/// Return `null` if the key is already set.
init(KeySize keySize) async {
if (this.key != null) return null;
this._keySize = keySize;
try {
this._key = await KeyGenerator().secretKey(keySize: keySize);
} on PlatformException catch (e) {
log(e.message, name: TAG_ERROR);
}
try {
this._isInitialized = _testKey();
} on KeyException catch (e) {
this._isInitialized = false;
throw e;
}
}
/// Encrypts data.
///
/// Takes `Uint8List` data as parameter.
/// And returns an `Uint8List` **list**.
///
/// You can pass a different key.
///
/// The first member of this list is the `cipher data`,
/// and the second member is the `IV`.
Future<List<Uint8List>> encrypt(Uint8List data, {Uint8List key}) async {
if (!this._isInitialized && key == null)
throw EncryptionException(
'Instance not initialized. You can pass a key directly in encrypt method.');
List<Uint8List> encryptedPayload =
await NativeCrypto().symEncrypt(data, key ?? this.key);
return encryptedPayload;
}
/// Decrypts data.
///
/// Takes `Uint8List` **list** as parameter.
/// And returns plain text data as `Uint8List`.
///
/// You can pass a different key.
Future<Uint8List> decrypt(List<Uint8List> encryptedPayload, {Uint8List key}) async {
if (!this._isInitialized && key == null)
throw DecryptionException(
'Instance not initialized. You can pass a key directly in decrypt method.');
Uint8List decryptedPayload;
try {
decryptedPayload = await NativeCrypto().symDecrypt(encryptedPayload, key ?? this.key);
} on DecryptionException catch (e) {
log(e.message, name: TAG_ERROR);
throw e;
}
return decryptedPayload;
}
}

66
melos.yaml Normal file
View File

@ -0,0 +1,66 @@
name: NativeCrypto
packages:
- packages/**
command:
bootstrap:
usePubspecOverrides: true
version:
updateGitTagRefs: true
linkToCommits: false # Gitea not yet supported
workspaceChangelog: true
branch: master
scripts:
lint:all:
run: melos run analyze && melos run format
description: Run all static analysis checks.
analyze:
run: |
melos exec -c 1 -- flutter analyze --fatal-infos
description: Run `flutter analyze` for all packages.
format:
run: melos exec flutter format . --fix
description: Run `flutter format` for all packages.
format-check:
run: melos exec flutter format . --set-exit-if-changed
description: Run `flutter format` checks for all packages.
clean:deep:
run: git clean -x -d -f -q
description: Clean things very deeply with `git clean`.
test:selective_unit_test:
run: melos exec -- flutter test --no-pub --coverage
description: Run Flutter tests for a specific package in this project.
select-package:
dir-exists:
- test
ignore:
- '*example*'
test:all:
run: melos run test:selective_unit_test --no-select
description: Run all Flutter tests in this project.
quality-check:
run: |
melos clean && \
melos bootstrap && \
melos run test:all
description: Run all targets generally expected in CI for a full local quality check.
publish:validate:
run: melos publish --diff="origin/$DRONE_COMMIT_BRANCH...HEAD" --yes
# publish:
# run: melos publish --diff="origin/$DRONE_COMMIT_BRANCH...HEAD" --no-dry-run --yes
# Additional cleanup lifecycle script, executed when `melos clean` is run.
postclean: >
melos exec -c 6 -- "flutter clean"

View File

@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited. # This file should be version controlled and should not be manually edited.
version: version:
revision: f139b11009aeb8ed2a3a3aa8b0066e482709dde3 revision: cf4400006550b70f28e4b4af815151d1e74846c6
channel: stable channel: stable
project_type: plugin project_type: plugin

View File

@ -0,0 +1,63 @@
## 0.2.0
> Note: This release has breaking changes.
- **REFACTOR**: (WIP) optimize exceptions and bytearray.
- **REFACTOR**: update benchmark page.
- **FIX**: accept empty decrypted plaintext.
- **FIX**: update code to pass tests.
- **FIX**: update code to pass all tests.
- **FIX**: change tag length in aes gcm cipher.
- **FEAT**: update example for ios file encryption.
- **FEAT**: update example with benchmark + file encryption.
- **FEAT**: update example.
- **FEAT**: rework bytearray and memory optimization, simplify API.
- **DOCS**: update readmes/licences.
- **DOCS**: update readme.
- **BREAKING** **FEAT**: rework full api with better object oriented architecture.
## 0.1.1
- **REFACTOR**: change file organization.
- **PERF**: x10 perfomance improvement on android with better list management.
- **FIX**: benchmark output.
- **FIX**: update and fix code.
- **FEAT**: export new exceptions.
- **FEAT**: add PointyCastle benchmark.
- **DOCS**: add link to readme file.
## 0.1.0
> Breaking changes !
* Follow **Federated Plugin** Flutter standard.
## 0.0.6
* Add KeyPair generation.
* Rework exposed API.
## 0.0.5
* New API.
* Add digest support.
* Clean platform specific code base.
## 0.0.4
* Improve AES.
## 0.0.3
* Add PBKDF2 support.
* Add exceptions.
* Improve documentation.
## 0.0.2
* Add different key size support.
* Improve performances.
## 0.0.1
* First AES cross-platform encryption & decryption implementation.

View File

@ -0,0 +1,23 @@
NativeCrypto
MIT License
Copyright (c) 2019 - 2023 Hugo Pointcheval
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,3 @@
# NativeCrypto
Readme available at [project root](../../README.md).

View File

@ -0,0 +1 @@
include: package:wyatt_analysis/analysis_options.flutter.yaml

View File

@ -22,6 +22,7 @@
# Flutter/Dart/Pub related # Flutter/Dart/Pub related
**/doc/api/ **/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/ .dart_tool/
.flutter-plugins .flutter-plugins
.flutter-plugins-dependencies .flutter-plugins-dependencies
@ -33,5 +34,13 @@
# Web related # Web related
lib/generated_plugin_registrant.dart lib/generated_plugin_registrant.dart
# Exceptions to above rules. # Symbolication related
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release

View File

@ -0,0 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.
version:
revision: cd41fdd495f6944ecd3506c21e94c6567b073278
channel: stable
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: cd41fdd495f6944ecd3506c21e94c6567b073278
base_revision: cd41fdd495f6944ecd3506c21e94c6567b073278
- platform: web
create_revision: cd41fdd495f6944ecd3506c21e94c6567b073278
base_revision: cd41fdd495f6944ecd3506c21e94c6567b073278
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

View File

@ -0,0 +1,15 @@
## 0.0.1
- **REFACTOR**: update benchmark page.
- **REFACTOR**: change file organization.
- **PERF**: x10 perfomance improvement on android with better list management.
- **FIX**: update code to pass all tests.
- **FIX**: benchmark output.
- **FIX**: update and fix code.
- **FEAT**: update example for ios file encryption.
- **FEAT**: update example with benchmark + file encryption.
- **FEAT**: update example.
- **FEAT**: rework bytearray and memory optimization, simplify API.
- **FEAT**: export new exceptions.
- **FEAT**: add PointyCastle benchmark.

View File

@ -0,0 +1 @@
include: package:wyatt_analysis/analysis_options.flutter.yaml

View File

@ -0,0 +1,13 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks

View File

@ -26,24 +26,28 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android { android {
compileSdkVersion 28 compileSdkVersion flutter.compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets { sourceSets {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
} }
lintOptions {
disable 'InvalidPackage'
}
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "fr.pointcheval.native_crypto_example" applicationId "fr.pointcheval.native_crypto_example"
minSdkVersion 16 minSdkVersion 26
targetSdkVersion 28 targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
@ -53,6 +57,7 @@ android {
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
} }
} }
namespace 'fr.pointcheval.native_crypto_example'
} }
flutter { flutter {
@ -61,7 +66,4 @@ flutter {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
} }

View File

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="fr.pointcheval.native_crypto_example">
<!-- Flutter needs it to communicate with the running application <!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->

View File

@ -1,21 +1,24 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="fr.pointcheval.native_crypto_example"> <application
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="native_crypto_example" android:label="native_crypto_example"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>

View File

@ -0,0 +1,6 @@
package fr.pointcheval.native_crypto_example
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="fr.pointcheval.native_crypto_example">
<!-- Flutter needs it to communicate with the running application <!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->

View File

@ -1,12 +1,12 @@
buildscript { buildscript {
ext.kotlin_version = '1.3.50' ext.kotlin_version = "1.6.21"
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.6.2' classpath 'com.android.tools.build:gradle:7.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
@ -14,7 +14,7 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
} }

View File

@ -1,4 +1,3 @@
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true

View File

@ -1,6 +1,6 @@
#Wed Apr 29 22:33:58 CEST 2020 #Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip

View File

@ -0,0 +1,11 @@
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"

View File

@ -1,3 +1,4 @@
**/dgph
*.mode1v3 *.mode1v3
*.mode2v3 *.mode2v3
*.moved-aside *.moved-aside
@ -18,6 +19,7 @@ Flutter/App.framework
Flutter/Flutter.framework Flutter/Flutter.framework
Flutter/Flutter.podspec Flutter/Flutter.podspec
Flutter/Generated.xcconfig Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx Flutter/app.flx
Flutter/app.zip Flutter/app.zip
Flutter/flutter_assets/ Flutter/flutter_assets/

View File

@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>en</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>App</string> <string>App</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>8.0</string> <string>11.0</string>
</dict> </dict>
</plist> </plist>

View File

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View File

@ -0,0 +1,41 @@
# Uncomment this line to define a global platform for your project
platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end

View File

@ -0,0 +1,75 @@
PODS:
- DKImagePickerController/Core (4.3.4):
- DKImagePickerController/ImageDataManager
- DKImagePickerController/Resource
- DKImagePickerController/ImageDataManager (4.3.4)
- DKImagePickerController/PhotoGallery (4.3.4):
- DKImagePickerController/Core
- DKPhotoGallery
- DKImagePickerController/Resource (4.3.4)
- DKPhotoGallery (0.0.17):
- DKPhotoGallery/Core (= 0.0.17)
- DKPhotoGallery/Model (= 0.0.17)
- DKPhotoGallery/Preview (= 0.0.17)
- DKPhotoGallery/Resource (= 0.0.17)
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Core (0.0.17):
- DKPhotoGallery/Model
- DKPhotoGallery/Preview
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Model (0.0.17):
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Preview (0.0.17):
- DKPhotoGallery/Model
- DKPhotoGallery/Resource
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Resource (0.0.17):
- SDWebImage
- SwiftyGif
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Flutter (1.0.0)
- native_crypto_ios (0.0.1):
- Flutter
- SDWebImage (5.15.5):
- SDWebImage/Core (= 5.15.5)
- SDWebImage/Core (5.15.5)
- SwiftyGif (5.4.4)
DEPENDENCIES:
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- Flutter (from `Flutter`)
- native_crypto_ios (from `.symlinks/plugins/native_crypto_ios/ios`)
SPEC REPOS:
trunk:
- DKImagePickerController
- DKPhotoGallery
- SDWebImage
- SwiftyGif
EXTERNAL SOURCES:
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
Flutter:
:path: Flutter
native_crypto_ios:
:path: ".symlinks/plugins/native_crypto_ios/ios"
SPEC CHECKSUMS:
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
file_picker: ce3938a0df3cc1ef404671531facef740d03f920
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
native_crypto_ios: de03ec2f594e8d41bcba2341b7ad57fd926ada5d
SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
PODFILE CHECKSUM: cc1f88378b4bfcf93a6ce00d2c587857c6008d3b
COCOAPODS: 1.11.3

View File

@ -3,21 +3,17 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 46; objectVersion = 54;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 57C8B66CEF3FCADD27359CF2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B565CC9BF59F330E881E6A5 /* Pods_Runner.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
D294241BEFD2D3EF500C0577 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6CB4DB73769DFCBF23FCC12 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -27,8 +23,6 @@
dstPath = ""; dstPath = "";
dstSubfolderSpec = 10; dstSubfolderSpec = 10;
files = ( files = (
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
); );
name = "Embed Frameworks"; name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -38,23 +32,21 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
2DBF05A146610778D425B9D9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; 2ABDB9EE0C984D50A4E8A819 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; }; 4276EDF2B0F07350DCE3D5A1 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
5CD4F461EBFD40A270B90468 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C6CB4DB73769DFCBF23FCC12 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9B565CC9BF59F330E881E6A5 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D3EC88B33A6F35C67BAC8349 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
FB0023B75BB4BD74C9F8D280 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -62,29 +54,28 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 57C8B66CEF3FCADD27359CF2 /* Pods_Runner.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
D294241BEFD2D3EF500C0577 /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
8C27A9C4EB5E71366C317BF8 /* Frameworks */ = { 56AFD4323C9A594E66DE3CA2 /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C6CB4DB73769DFCBF23FCC12 /* Pods_Runner.framework */, 4276EDF2B0F07350DCE3D5A1 /* Pods-Runner.debug.xcconfig */,
2ABDB9EE0C984D50A4E8A819 /* Pods-Runner.release.xcconfig */,
5CD4F461EBFD40A270B90468 /* Pods-Runner.profile.xcconfig */,
); );
name = Frameworks; name = Pods;
path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEBA1CF902C7004384FC /* Flutter.framework */,
9740EEB21CF90195004384FC /* Debug.xcconfig */, 9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */,
@ -98,8 +89,8 @@
9740EEB11CF90186004384FC /* Flutter */, 9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
9F5A6E791DB57C1B2E0BF33E /* Pods */, 56AFD4323C9A594E66DE3CA2 /* Pods */,
8C27A9C4EB5E71366C317BF8 /* Frameworks */, CECC25F8D34DF7912A93B0E6 /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -118,7 +109,6 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */, 97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
@ -127,22 +117,12 @@
path = Runner; path = Runner;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
97C146F11CF9000F007C117D /* Supporting Files */ = { CECC25F8D34DF7912A93B0E6 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
9B565CC9BF59F330E881E6A5 /* Pods_Runner.framework */,
); );
name = "Supporting Files"; name = Frameworks;
sourceTree = "<group>";
};
9F5A6E791DB57C1B2E0BF33E /* Pods */ = {
isa = PBXGroup;
children = (
FB0023B75BB4BD74C9F8D280 /* Pods-Runner.debug.xcconfig */,
2DBF05A146610778D425B9D9 /* Pods-Runner.release.xcconfig */,
D3EC88B33A6F35C67BAC8349 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
/* End PBXGroup section */ /* End PBXGroup section */
@ -152,14 +132,14 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
D72ACB84F79B4AD23991D136 /* [CP] Check Pods Manifest.lock */, C54B0935BA386F7769969821 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
FF811A27CCC4B4D5EBD756CE /* [CP] Embed Pods Frameworks */, D9E654BBB4893905628A201A /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -176,8 +156,8 @@
97C146E61CF9000F007C117D /* Project object */ = { 97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1020; LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "The Chromium Authors"; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1; CreatedOnToolsVersion = 7.3.1;
@ -186,7 +166,7 @@
}; };
}; };
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 9.3";
developmentRegion = en; developmentRegion = en;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
@ -220,6 +200,7 @@
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -230,10 +211,11 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
}; };
9740EEB61CF901F6004384FC /* Run Script */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -246,7 +228,7 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
}; };
D72ACB84F79B4AD23991D136 /* [CP] Check Pods Manifest.lock */ = { C54B0935BA386F7769969821 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@ -268,15 +250,17 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
FF811A27CCC4B4D5EBD756CE /* [CP] Embed Pods Frameworks */ = { D9E654BBB4893905628A201A /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputPaths = ( inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
); );
name = "[CP] Embed Pods Frameworks"; name = "[CP] Embed Pods Frameworks";
outputPaths = ( outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
@ -319,7 +303,6 @@
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = { 249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
@ -359,7 +342,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -375,16 +358,12 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6Z5P8GG96U;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoExample; PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoExample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -396,7 +375,6 @@
}; };
97C147031CF9000F007C117D /* Debug */ = { 97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
@ -442,7 +420,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -452,7 +430,6 @@
}; };
97C147041CF9000F007C117D /* Release */ = { 97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
@ -492,11 +469,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };
@ -509,16 +487,12 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6Z5P8GG96U;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoExample; PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoExample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -536,16 +510,12 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6Z5P8GG96U;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoExample; PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoExample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";

View File

@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1020" LastUpgradeVersion = "1300"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@ -27,8 +27,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion> <MacroExpansion>
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
@ -38,8 +36,8 @@
ReferencedContainer = "container:Runner.xcodeproj"> ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference> </BuildableReference>
</MacroExpansion> </MacroExpansion>
<AdditionalOptions> <Testables>
</AdditionalOptions> </Testables>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Debug" buildConfiguration = "Debug"
@ -61,8 +59,6 @@
ReferencedContainer = "container:Runner.xcodeproj"> ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction> </LaunchAction>
<ProfileAction <ProfileAction
buildConfiguration = "Profile" buildConfiguration = "Profile"

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -4,6 +4,8 @@
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Native Crypto</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@ -40,6 +42,14 @@
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
</array> </array>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UISupportsDocumentBrowser</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
</dict> </dict>
</plist> </plist>

View File

@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

View File

@ -0,0 +1,35 @@
// Copyright 2019-2023 Hugo Pointcheval
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import 'package:get_it/get_it.dart';
import 'package:native_crypto_example/data/data_sources/logger_data_source_impl.dart';
import 'package:native_crypto_example/data/data_sources/native_crypto_data_source_impl.dart';
import 'package:native_crypto_example/data/data_sources/pointy_castle_data_source_impl.dart';
import 'package:native_crypto_example/data/data_sources/session_data_source_impl.dart';
import 'package:native_crypto_example/domain/data_sources/logger_data_source.dart';
import 'package:native_crypto_example/domain/data_sources/session_data_source.dart';
final getIt = GetIt.I;
abstract class GetItInitializer {
static Future<void> init() async {
getIt
..registerLazySingleton<SessionDataSource>(
SessionDataSourceImpl.new,
)
..registerLazySingleton<LoggerDataSource>(
LoggerDataSourceImpl.new,
)
..registerLazySingleton<NativeCryptoDataSourceImpl>(
NativeCryptoDataSourceImpl.new,
)
..registerLazySingleton<PointyCastleDataSourceImpl>(
PointyCastleDataSourceImpl.new,
);
await getIt.allReady();
}
}

View File

@ -0,0 +1,18 @@
// Copyright 2019-2023 Hugo Pointcheval
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import 'package:flutter/material.dart';
abstract class AppTypography {
static const title = TextStyle(
color: Colors.black,
fontSize: 24,
);
static const body = TextStyle(
fontSize: 16,
);
}

Some files were not shown because too many files have changed in this diff Show More