WIP WIP WIP crypto
This commit is contained in:
		
							parent
							
								
									67da1e4922
								
							
						
					
					
						commit
						e5dc2242c4
					
				
					 7 changed files with 3497 additions and 12 deletions
				
			
		| 
						 | 
					@ -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
									
								
							
							
						
						
									
										3442
									
								
								examples/publish-js/package-lock.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										6
									
								
								examples/publish-js/package.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								examples/publish-js/package.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "browserify": "^17.0.0",
 | 
				
			||||||
 | 
					    "jose": "^4.8.3"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								examples/publish-js/publish-encrypted.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								examples/publish-js/publish-encrypted.html
									
										
									
									
									
										Normal 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>
 | 
				
			||||||
							
								
								
									
										7
									
								
								examples/publish-js/publish-encrypted.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								examples/publish-js/publish-encrypted.js
									
										
									
									
									
										Normal 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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								examples/publish-js/publish.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								examples/publish-js/publish.html
									
										
									
									
									
										Normal 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>
 | 
				
			||||||
| 
						 | 
					@ -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()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue