1
0
Fork 0
mirror of https://github.com/binwiederhier/ntfy.git synced 2024-11-23 19:59:26 +01:00

WIP WIP WIP crypto

This commit is contained in:
Philipp Heckel 2022-07-08 08:16:03 -04:00
parent 67da1e4922
commit e5dc2242c4
7 changed files with 3497 additions and 12 deletions

View file

@ -100,6 +100,7 @@ func execPublish(c *cli.Context) error {
noFirebase := c.Bool("no-firebase") noFirebase := c.Bool("no-firebase")
quiet := c.Bool("quiet") quiet := c.Bool("quiet")
pid := c.Int("wait-pid") pid := c.Int("wait-pid")
//password := os.Getenv("NTFY_PASSWORD")
topic, message, command, err := parseTopicMessageCommand(c) topic, message, command, err := parseTopicMessageCommand(c)
if err != nil { if err != nil {
return err return err

3442
examples/publish-js/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,6 @@
{
"dependencies": {
"browserify": "^17.0.0",
"jose": "^4.8.3"
}
}

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Publish to ntfy.sh</title>
</head>
<body>
<input id="password" placeholder="Topic password"/>
<button onclick="publish()">Publish encrypted message</button>
</body>
<script async src="https://unpkg.com/jose@4.8.3/dist/browser/jwe/compact/encrypt.js" type="module"></script>
<script async src="publish-encrypted.js" type="module"></script>
</html>

View file

@ -0,0 +1,7 @@
import * as jose from 'jose'
async function publish() {
const jwe = await new jose.CompactEncrypt(new TextEncoder().encode('Secret message from JS!'))
.setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })
.encrypt(publicKey)
}

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Publish to ntfy.sh</title>
</head>
<body>
<button onclick="publish()">Publish</button>
</body>
<script>
function publish() {
fetch('https://ntfy.sh/mytopic', {
method: 'POST', // PUT works too
body: 'Backup successful 😀'
});
}
</script>
</html>

View file

@ -2,41 +2,39 @@
import requests import requests
import json
from base64 import b64encode, urlsafe_b64encode, b64decode from base64 import b64encode, urlsafe_b64encode, b64decode
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Protocol.KDF import PBKDF2 from Crypto.Protocol.KDF import PBKDF2
from Crypto.Hash import SHA256 from Crypto.Hash import SHA256
from Crypto.Random import get_random_bytes from Crypto.Random import get_random_bytes
def derive_key(password, topic_url): def derive_key(password, topic_url):
salt = SHA256.new(data=topic_url.encode('utf-8')).digest() salt = SHA256.new(data=topic_url.encode('utf-8')).digest()
return PBKDF2(password, salt, 32, count=50000, hmac_hash_module=SHA256) return PBKDF2(password, salt, 32, count=50000, hmac_hash_module=SHA256)
def encrypt(plaintext, key): def encrypt(plaintext, key):
encoded_header = b64urlencode('{"alg":"dir","enc":"A256GCM"}'.encode('utf-8')) encoded_header = b64urlencode('{"alg":"dir","enc":"A256GCM"}'.encode('utf-8'))
iv = get_random_bytes(12) # GCM is used with a 96-bit IV iv = get_random_bytes(12) # GCM is used with a 96-bit IV
aad = encoded_header aad = encoded_header
cipher = AES.new(key, AES.MODE_GCM, nonce=iv) cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
cipher.update(aad.encode('utf-8')) cipher.update(aad.encode('utf-8'))
ciphertext, tag = cipher.encrypt_and_digest(plaintext.encode('utf-8')) ciphertext, tag = cipher.encrypt_and_digest(plaintext.encode('utf-8'))
return "{header}..{iv}.{ciphertext}.{tag}".format( return "{header}..{iv}.{ciphertext}.{tag}".format(
header = encoded_header, header=encoded_header,
iv = b64urlencode(iv), iv=b64urlencode(iv),
ciphertext = b64urlencode(ciphertext), ciphertext=b64urlencode(ciphertext),
tag = b64urlencode(tag) tag=b64urlencode(tag)
) )
def b64urlencode(b): def b64urlencode(b):
return urlsafe_b64encode(b).decode('utf-8').replace("=", "") return urlsafe_b64encode(b).decode('utf-8').replace("=", "")
key = derive_key("secr3t password", "https://ntfy.sh/mysecret") key = derive_key("secr3t password", "https://ntfy.sh/mysecret")
ciphertext = encrypt('{"message":"Python says hi","tags":["secret"]}', key) ciphertext = encrypt('{"message":"Python says hi","tags":["secret"]}', key)
resp = requests.post("https://ntfy.sh/mysecret", resp = requests.post("https://ntfy.sh/mysecret", data=ciphertext, headers={"Encryption": "jwe"})
data=ciphertext,
headers={
"Encryption": "jwe"
})
resp.raise_for_status() resp.raise_for_status()