Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
DuniterPy
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
clients
python
DuniterPy
Commits
821a3b9f
Commit
821a3b9f
authored
6 years ago
by
Vincent Texier
Browse files
Options
Downloads
Patches
Plain Diff
[enh]
#78
Add Ascii Armor encrypted and signed message creation and example
parent
d790538f
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
duniterpy/key/__init__.py
+3
-2
3 additions, 2 deletions
duniterpy/key/__init__.py
duniterpy/key/ascii_armor.py
+123
-0
123 additions, 0 deletions
duniterpy/key/ascii_armor.py
examples/save_ascii_armor_encrypted_message.py
+35
-0
35 additions, 0 deletions
examples/save_ascii_armor_encrypted_message.py
with
161 additions
and
2 deletions
duniterpy/key/__init__.py
+
3
−
2
View file @
821a3b9f
from
.signing_key
import
SigningKey
,
ScryptParams
from
.signing_key
import
SigningKey
from
.verifying_key
import
VerifyingKey
from
.encryption_key
import
SecretKey
,
PublicKey
from
.encryption_key
import
SecretKey
,
PublicKey
,
SCRYPT_PARAMS
,
SEED_LENGTH
from
.ascii_armor
import
AsciiArmor
This diff is collapsed.
Click to expand it.
duniterpy/key/ascii_armor.py
0 → 100644
+
123
−
0
View file @
821a3b9f
import
base64
import
libnacl
from
typing
import
Optional
,
List
from
duniterpy.key
import
SigningKey
,
PublicKey
,
SCRYPT_PARAMS
,
SEED_LENGTH
# Headers constants
BEGIN_MESSAGE_HEADER
=
"
-----BEGIN DUNITER MESSAGE-----
"
END_MESSAGE_HEADER
=
"
-----END DUNITER MESSAGE-----
"
BEGIN_SIGNATURE_HEADER
=
"
-----BEGIN DUNITER SIGNATURE-----
"
END_SIGNATURE_HEADER
=
"
-----END DUNITER SIGNATURE-----
"
# Version field values
AA_MESSAGE_VERSION
=
"
Python Libnacl
"
+
libnacl
.
__version__
AA_SIGNATURE_VERSION
=
"
Python Libnacl
"
+
libnacl
.
__version__
class
AsciiArmor
:
"""
Class to handle writing and reading of ascii armor messages
"""
@staticmethod
def
encrypt
(
message
:
str
,
pubkey
:
str
,
signing_keys
:
Optional
[
List
[
SigningKey
]]
=
None
,
message_comment
:
Optional
[
str
]
=
None
,
signatures_comment
:
Optional
[
str
]
=
None
)
->
str
:
"""
Encrypt a message in ascii armor format, optionally signing it
:param message: Utf-8 message
:param pubkey: Public key of recipient for encryption
:param signing_keys: Optional list of SigningKey instances
:param message_comment: Optional message comment field
:param signatures_comment: Optional signatures comment field
:return:
"""
pubkey_instance
=
PublicKey
(
pubkey
)
base64_encrypted_message
=
base64
.
b64encode
(
pubkey_instance
.
encrypt_seal
(
message
))
# type: bytes
script_field
=
AsciiArmor
.
_get_scrypt_field
()
# create block with headers
ascii_armor_msg
=
"""
{begin_message_header}
Version: {version}
{script_field}
"""
.
format
(
begin_message_header
=
BEGIN_MESSAGE_HEADER
,
version
=
AA_MESSAGE_VERSION
,
script_field
=
script_field
)
# add message comment if specified
if
message_comment
:
ascii_armor_msg
+=
AsciiArmor
.
_get_comment_field
(
message_comment
)
# add encrypted message
ascii_armor_msg
+=
"""
{base64_encrypted_message}
"""
.
format
(
base64_encrypted_message
=
base64_encrypted_message
.
decode
(
'
utf-8
'
))
# if no signature...
if
signing_keys
is
None
:
# add message tail
ascii_armor_msg
+=
END_MESSAGE_HEADER
else
:
# add signature blocks and close block on last signature
count
=
1
for
signing_key
in
signing_keys
:
ascii_armor_msg
+=
AsciiArmor
.
_get_signature_block
(
message
,
signing_key
,
count
==
len
(
signing_keys
),
signatures_comment
)
count
+=
1
return
ascii_armor_msg
@staticmethod
def
_get_scrypt_field
():
"""
Return the Scrypt field
:return:
"""
return
"
Scrypt: N={0};r={1};p={2};len={3}
"
.
format
(
SCRYPT_PARAMS
[
'
N
'
],
SCRYPT_PARAMS
[
'
r
'
],
SCRYPT_PARAMS
[
'
p
'
],
SEED_LENGTH
)
@staticmethod
def
_get_comment_field
(
comment
:
str
)
->
str
:
"""
Return a comment field
:param comment: Comment text
:return:
"""
return
"
Comment: {comment}
\n
"
.
format
(
comment
=
comment
)
@staticmethod
def
_get_signature_block
(
message
:
str
,
signing_key
:
SigningKey
,
close_block
:
bool
=
True
,
comment
:
Optional
[
str
]
=
None
)
->
str
:
"""
Return a signature block
:param message: Message (not encrypted!) to sign
:param signing_key: The libnacl SigningKey instance of the keypair
:param close_block: Optional flag to close the signature block with the signature tail header
:param comment: Optional comment field content
:return:
"""
script_param_field
=
AsciiArmor
.
_get_scrypt_field
()
base64_signature
=
base64
.
b64encode
(
signing_key
.
signature
(
message
))
block
=
"""
{begin_signature_header}
Version: {version}
Scrypt: {script_params}
"""
.
format
(
begin_signature_header
=
BEGIN_SIGNATURE_HEADER
,
version
=
AA_SIGNATURE_VERSION
,
script_params
=
script_param_field
)
# add message comment if specified
if
comment
:
block
+=
AsciiArmor
.
_get_comment_field
(
comment
)
block
+=
"""
{base64_signature}
"""
.
format
(
base64_signature
=
base64_signature
.
decode
(
'
utf-8
'
))
if
close_block
:
block
+=
END_SIGNATURE_HEADER
return
block
This diff is collapsed.
Click to expand it.
examples/save_ascii_armor_encrypted_message.py
0 → 100644
+
35
−
0
View file @
821a3b9f
import
getpass
from
duniterpy
import
__version__
from
duniterpy.key
import
AsciiArmor
,
SigningKey
################################################
AA_ENCRYPTED_MESSAGE_FILENAME
=
'
duniter_aa_encrypted_message.txt
'
if
__name__
==
'
__main__
'
:
# Ask public key of the recipient
pubkeyBase58
=
input
(
"
Enter public key of the message recipient:
"
)
# prompt hidden user entry
salt
=
getpass
.
getpass
(
"
Enter your passphrase (salt):
"
)
# prompt hidden user entry
password
=
getpass
.
getpass
(
"
Enter your password:
"
)
# init SigningKey instance
signing_key
=
SigningKey
.
from_credentials
(
salt
,
password
)
# Enter the message
message
=
input
(
"
Enter your message:
"
)
comment
=
"
generated by Duniterpy {0}
"
.
format
(
__version__
)
# Encrypt the message, only the recipient secret key will be able to decrypt the message
encrypted_message
=
AsciiArmor
.
encrypt
(
message
,
pubkeyBase58
,
[
signing_key
],
message_comment
=
comment
,
signatures_comment
=
comment
)
# Save encrypted message in a file
with
open
(
AA_ENCRYPTED_MESSAGE_FILENAME
,
'
w
'
)
as
file_handler
:
file_handler
.
write
(
encrypted_message
)
print
(
"
Ascii Armor Encrypted message saved in file ./{0}
"
.
format
(
AA_ENCRYPTED_MESSAGE_FILENAME
))
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment