web-push-libs / encrypted-content-encoding Goto Github PK
View Code? Open in Web Editor NEWA simple implementation of the encrypted content-encoding
License: MIT License
A simple implementation of the encrypted content-encoding
License: MIT License
Several folks have reported issues with versions of the crypto lib < 1.9.
I'm working on generating some test vectors with different pad and record sizes for ecec and Firefox, and I have a couple of questions.
Include crypto function fix,
update to cryptography 2.5 +
The dependency pyelliptic has been deprecated and should probably be replaced.
A workaround for now would be to pin the version of pyelliptic to 1.5.7. (that fixed it for us)
Background info:
Discovered it because Home Assistant CI started failing after pyelliptic 1.5.8 was released today which removes the ECC part: yann2192/pyelliptic@7157714
In Node Js this done as follows:
const crypto = require('crypto');
const ece = require('http_ece');
const dh = crypto.createECDH('prime256v1');
dh.setPrivateKey("d25a7249abac3beae6d03e0441867de762ea4cfc51e5c202a3fc0a45486d1f94", 'hex');
const params = {
version: 'aes128gcm',
authSecret: "a7omShAT1ycPQqu9UHaS6Q",
privateKey: dh,
};
const buf = Buffer.from(array2, 'hex');
const decrypted = ece.decrypt(buf, params);
console.log(decrypted.toString());
I think your version pinning of the cryptography package is syntactically wrong, isn't it. This probably prevents installing pywebpush via pip:
pip3 install pywebpush
Collecting pywebpush
Using cached pywebpush-1.0.5.tar.gz
Requirement already satisfied: cryptography<1.10,>=1.8.1 in /srv/homeassistant/lib/python3.4/site-packages (from pywebpush)
Collecting http-ece>=1.0.1 (from pywebpush)
Using cached http_ece-1.0.2.tar.gz
Complete output from command python setup.py egg_info:
error in http_ece setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-q1sixmvm/http-ece/
Let's say I encrypt some data using the standard parameters from PushSubscription.toJSON()
(generated in js and sent to the sever), how do I decypt that data?
I've tried numerous combinations, but nothing working. I've looked through the unit tests but I'm not getting anywhere.
To make the question more concrete:
import base64
import time
from devtools import debug
import http_ece
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec
from py_vapid import Vapid02 as Vapid
private_key = (
'MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgvGPhHfTSfxCod+wT'
'zLuyK8KWjPGGvKJKJjzBGSF47YuhRANCAAQJNQfHBSOe5nI5fmUcwTFw3ckqXXvR'
'F632vcMyB9RxPMaxicdqPiLg45GIk9oeEtm1kQjHQe7ikWxPFAm7uxkB'
)
public_key = (
'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECTUHxwUjnuZyOX5lHMExcN3JKl17'
'0Ret9r3DMgfUcTzGsYnHaj4i4OORiJPaHhLZtZEIx0Hu4pFsTxQJu7sZAQ=='
)
applicationServerKey = 'BAk1B8cFI57mcjl-ZRzBMXDdySpde9EXrfa9wzIH1HE8xrGJx2o-IuDjkYiT2h4S2bWRCMdB7uKRbE8UCbu7GQE'
# generated with js:
p256dh = 'BB9VI8Aud-V2zXwzQzqRTQEGBipFFCr9Y0IRTTY7aRC6dJXowEZoCHS_xMTl_dc0cSmvl6_c9oWssQNrdzoj87o'
auth = 'WPIxwcp38j79qh_mbp_IAg'
vapid_encoding = 'aes128gcm'
def _prepare_vapid_key(data: str) -> bytes:
"""
Add base64 padding to the end of a string, if required
"""
data = data.encode() + b'===='[: len(data) % 4]
return base64.urlsafe_b64decode(data)
server_key = ec.generate_private_key(ec.SECP256R1, default_backend())
enc = http_ece.encrypt(
b'this is a test',
private_key=server_key,
dh=_prepare_vapid_key(p256dh),
auth_secret=_prepare_vapid_key(auth),
version=vapid_encoding,
)
vapid_claims = {'aud': 'https://example.com', 'sub': 'mailto:[email protected]', 'ext': int(time.time()) + 12 * 3600}
auth_header = Vapid.from_string(private_key=private_key).sign(vapid_claims)['Authorization']
debug(enc, auth_header)
data = http_ece.decrypt(enc, ...) # <-- What do I need here?
debug(data)
Also many of the type hints in docstrings refer to str
when they should be bytes
.
Update minor version to 1.2.0 to include changes from #68.
A security release of openssl broke one of the calls pyca/cryptography#2750, which will prevent http_ece from installing if there's an existing library that uses a later install of cryptography.
Please update the dependency from 1.1.0 to 1.8.1
While using package electron-push-receiver to listen firebase notification and when we update this package, this updates its internal dependency package http-ece from v1.1.0 to v1.2.0. So in version 1.2.0 its not working. Tried removing caret symbol from http-ece inside node_modules folder inside push-receiver folder. So it wont update to 1.2.0, now it's working
There are tests, and they should be run for PRs.
cc @jrconlin
Library update
Hi I'm having an issue installing this package:
❯ pip install --user http_ece
Collecting http_ece
Using cached http_ece-1.0.1.tar.gz
Complete output from command python setup.py egg_info:
error in http_ece setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers
----------------------------------------
Any clue why this is happening?
In python implementation (init.py, line 76):
++counter
python hasn't ++
operator, so the counter is not incremented and initial vector for all the blocks is the same.
With the fix for #6.
Firefox 45 is long gone, we could remove the branch here: https://github.com/martinthomson/encrypted-content-encoding/blob/master/nodejs/ece.js#L146.
I noticed that https://github.com/web-push-libs/encrypted-content-encoding/blob/master/nodejs/ece.js#L264 still uses "saved" even though it's been removed.
The encode_point method used in tests was removed in cryptography 39.0.0.
Hi! I'm not very proficient with js and didn't investigate this document too much, but it seems to me you have wrong usage of padding ('ece.js', line 145):
var padding = new Buffer(pad + 1);
here you initialize padding with some random bytes allocated for it, however in the specification it should be a length byte, then zero bytes.
A receiver MUST fail to decrypt if any padding octet other than the first is
non-zero, or a record has more padding than the record size can
accommodate.
So, it seems this implementation is contradicting with this document.
By the way, function encryptRecord
is nowhere used with padding parameter, so it's always zero.
Sorry if I'm treating anything wrong.
Hi, I was wondering if I could start a PHP implementation.
The problem is that there is no library at the moment that handle AES GCM mode. The PHP binding of OpenSSL lists GCM as available but there is currently no way to retrieve the authentication tag (see bug issue).
Is there a way to support your spec without GCM ? I guess not, but I need to ask. :)
My final goal is to be able to encrypt payload for my WebPush PHP library.
Why there is no 1.1.0 version available in github releases and is available on pypi?
Can you please release a new version on github too?
Thanks.
node.js implementation could not be used with unicode strings:
>encrypt("й",parameters).length
18
this symbol is 2-bytes long, but is treated as one byte.
@jrconlin Are you able to do a branch rename for me?
Starting to see a bunch of these. Looks like the call needs to be updated.
http_ece/__init__.py:72: CryptographyDeprecationWarning: Support for unsafe construction of public numbers from encoded data will be removed in a future version. Please use EllipticCurvePublicKey.from_encoded_point
numbers = ec.EllipticCurvePublicNumbers.from_encoded_point(ec.SECP256R1(), dh)
I have a small python module that I am using to test the mozilla web push api. Version 0.2.0 worked fine; however after upgrading to 0.4.0, the code no longer works. I took a look at the master branch and I couldn't find a change that would explain the failure.
decrypt uses the base4 encoded dh value, which will fail to be recognized later.
Since pyelliptic is no longer supported, and cryptography 1.1 added ECDH support, that seems like a reasonable way to go.
Hi guys:
[Just a FYI and probably this bug is quite challenge to be fixed.]
I got ImportError: No module named cryptography.hazmat.bindings._constant_time error while importing http_ece due to GAE doesn't support most of C extension libraries.
Reference:
cryptography issue 2161
The former is available as part of the standard runtime environment in the google cloud product.
NOTE: Please test in a least two browsers (i.e. Chrome and Firefox). This
helps with diagnosing problems quicker.
Please provide the following details, the more info you can provide the
better.
Operating System: AWS Lambda | Windows
Node Version: 18.10.0
web-push Version: 3.6.2
http-ece Version: 1.1.0
Please select any browsers that you are experiencing problems with:
Please list the browsers you are have tested this, including the version
of the browser (i.e. Chrome Beta, Firefox Beta etc).
When calling web-push sendNotification in Node18 I see the following console error:
ERROR (node:14) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
at showFlaggedDeprecation (node:buffer:195:11)
at new Buffer (node:buffer:279:3)
at Object.decode (/var/task/index.js:490:68353)
at Object.validatePublicKey (/var/task/index.js:493:8952)
at sendNotification (/var/task/index.js:497:4174)
...
There is a similar, fixed issue, (web-push-libs/web-push#785) that handled removing direct calls to urlSafe-base64. There is also a urlSafe-base64 call http-ece that causes the same issue. Workaround was to pull dependency code into my project and fix the call in http-ece.
No console errors
Please provide a code sample that reproduces the issue. If there is a
repository that reproduces the issue please put the link here.
import webpush from "web-push";
webpush.sendNotification(subscription, payload);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.