Popular New Releases in Cryptography
dogecoin
Dogecoin Core 1.14.4
tink
Tink 1.6.1
Ciphey
General cleanup + new look
CryptoSwift
xmrig
Popular Libraries in Cryptography
by dogecoin c++
12895 MIT
very currency
by google c++
12235 Apache-2.0
Tink is a multi-language, cross-platform, open source library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse.
by brix javascript
11655 NOASSERTION
JavaScript library of crypto standards.
by Ciphey python
9435 MIT
⚡ Automatically decrypt encryptions without knowing the key or cipher, decode encodings, and crack hashes ⚡
by jedisct1 c
9355 NOASSERTION
A modern, portable, easy to use crypto library.
by krzyzanowskim swift
9011 NOASSERTION
CryptoSwift is a growing collection of standard and secure cryptographic algorithms implemented in Swift
by xmrig c
6840 GPL-3.0
RandomX, KawPow, CryptoNight, AstroBWT and GhostRider unified CPU/GPU miner and RandomX benchmark
by bitwiseshiftleft javascript
6721 NOASSERTION
Stanford Javascript Crypto Library
by drduh shell
6211 MIT
Guide to using YubiKey for GPG and SSH
Trending New libraries in Cryptography
by DP-3T shell
2245
Decentralized Privacy-Preserving Proximity Tracing -- Documents
by openethereum rust
1521 NOASSERTION
The fast, light, and robust client for the Ethereum mainnet.
by saljam go
1474 BSD-3-Clause
Peer authenticated WebRTC.
by kdrag0n c++
1164 NOASSERTION
A universal fix for Google SafetyNet on Android devices with hardware attestation and unlocked bootloaders.
by signalapp rust
997 AGPL-3.0
Home to the Signal Protocol as well as other cryptographic primitives which make Signal possible.
by ollypwn ruby
855
PoC for CVE-2020-0601- Windows CryptoAPI (Crypt32.dll)
by karpathy jupyter notebook
710
Pure Python from-scratch zero-dependency implementation of Bitcoin for educational purposes
by rabetofficial typescript
692
:rabbit: :earth_americas: Rabet browser extension enables you to manage your assets and interact with Stellar apps.
by curvefi python
689 NOASSERTION
Vyper contracts used in Curve.fi exchange pools.
Top Authors in Cryptography
1
39 Libraries
13451
2
21 Libraries
1279
3
19 Libraries
2304
4
17 Libraries
1776
5
14 Libraries
24526
6
13 Libraries
1096
7
12 Libraries
5757
8
12 Libraries
263
9
11 Libraries
932
10
11 Libraries
130
1
39 Libraries
13451
2
21 Libraries
1279
3
19 Libraries
2304
4
17 Libraries
1776
5
14 Libraries
24526
6
13 Libraries
1096
7
12 Libraries
5757
8
12 Libraries
263
9
11 Libraries
932
10
11 Libraries
130
Trending Kits in Cryptography
No Trending Kits are available at this moment for Cryptography
Trending Discussions on Cryptography
WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64 error using Selenium Geckodriver Firefox in FreeBSD jail
Crypto-js encryption and Python decryption using HKDF key
Poetry | AttributeError 'Link' object has no attribute 'name'
Django mod_wsgi Apache Server, ModuleNotFoundError: No Module Named Django
Encrypt data in Javascript, Decrypt data in C# using private/public keys
Export Certificate as PFX with proper chain of signing
When upgrading to .NET 6, Web Project throws runtime exception
Why are signatures created with ecdsa Python library not valid with coincurve?
Signing payload in JS (Frontend) using EC and validating in Python
convert base-64 spki string into public key
QUESTION
WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64 error using Selenium Geckodriver Firefox in FreeBSD jail
Asked 2022-Apr-01 at 07:54For some tests, I've set up a plain new TrueNAS 12.3 FreeBSD Jail and started it, then installed python3
, firefox
, geckodriver
and pip
using the following commands:
1pkg install python3 firefox geckodriver py38-pip
2pip install --upgrade pip
3setenv CRYPTOGRAPHY_DONT_BUILD_RUST 1
4pip install cryptography==3.4.7
5pip install selenium
6
Afterwards, when I want to use Selenium with Firefox in my Python code, it does not work:
1pkg install python3 firefox geckodriver py38-pip
2pip install --upgrade pip
3setenv CRYPTOGRAPHY_DONT_BUILD_RUST 1
4pip install cryptography==3.4.7
5pip install selenium
6from selenium import webdriver
7from selenium.webdriver.firefox.options import Options
8options = Options()
9options.headless = True
10driver = webdriver.Firefox(options=options)
11
it brings
1pkg install python3 firefox geckodriver py38-pip
2pip install --upgrade pip
3setenv CRYPTOGRAPHY_DONT_BUILD_RUST 1
4pip install cryptography==3.4.7
5pip install selenium
6from selenium import webdriver
7from selenium.webdriver.firefox.options import Options
8options = Options()
9options.headless = True
10driver = webdriver.Firefox(options=options)
11Traceback (most recent call last):
12 File "<stdin>", line 1, in <module>
13 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/firefox/webdriver.py", line 174, in __init__
14 self.service.start()
15 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 98, in start
16 self.assert_process_still_running()
17 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 110, in assert_process_still_running
18 raise WebDriverException(
19selenium.common.exceptions.WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64
20
Funnily, on another Jail that I've set up approximately a year ago (approximately in the mentioned way as well), it just works and does not throw the error (so different versions maybe?)!
This is the only content of geckodriver.log
:
1pkg install python3 firefox geckodriver py38-pip
2pip install --upgrade pip
3setenv CRYPTOGRAPHY_DONT_BUILD_RUST 1
4pip install cryptography==3.4.7
5pip install selenium
6from selenium import webdriver
7from selenium.webdriver.firefox.options import Options
8options = Options()
9options.headless = True
10driver = webdriver.Firefox(options=options)
11Traceback (most recent call last):
12 File "<stdin>", line 1, in <module>
13 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/firefox/webdriver.py", line 174, in __init__
14 self.service.start()
15 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 98, in start
16 self.assert_process_still_running()
17 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 110, in assert_process_still_running
18 raise WebDriverException(
19selenium.common.exceptions.WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64
20geckodriver: error: Found argument '--websocket-port' which wasn't expected, orisn't valid in this context
21
22USAGE:
23 geckodriver [FLAGS] [OPTIONS]
24
25For more information try --help
26
Is there anything I could try to get it working? I've already seen this question, but it seems fairly outdated.
Firefox 95.0.2, geckodriver 0.26.0, Python 3.8.12, Selenium 4.1.0
ANSWER
Answered 2022-Jan-23 at 16:48This error message...
1pkg install python3 firefox geckodriver py38-pip
2pip install --upgrade pip
3setenv CRYPTOGRAPHY_DONT_BUILD_RUST 1
4pip install cryptography==3.4.7
5pip install selenium
6from selenium import webdriver
7from selenium.webdriver.firefox.options import Options
8options = Options()
9options.headless = True
10driver = webdriver.Firefox(options=options)
11Traceback (most recent call last):
12 File "<stdin>", line 1, in <module>
13 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/firefox/webdriver.py", line 174, in __init__
14 self.service.start()
15 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 98, in start
16 self.assert_process_still_running()
17 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 110, in assert_process_still_running
18 raise WebDriverException(
19selenium.common.exceptions.WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64
20geckodriver: error: Found argument '--websocket-port' which wasn't expected, orisn't valid in this context
21
22USAGE:
23 geckodriver [FLAGS] [OPTIONS]
24
25For more information try --help
26selenium.common.exceptions.WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64
27
and the GeckoDriver log...
1pkg install python3 firefox geckodriver py38-pip
2pip install --upgrade pip
3setenv CRYPTOGRAPHY_DONT_BUILD_RUST 1
4pip install cryptography==3.4.7
5pip install selenium
6from selenium import webdriver
7from selenium.webdriver.firefox.options import Options
8options = Options()
9options.headless = True
10driver = webdriver.Firefox(options=options)
11Traceback (most recent call last):
12 File "<stdin>", line 1, in <module>
13 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/firefox/webdriver.py", line 174, in __init__
14 self.service.start()
15 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 98, in start
16 self.assert_process_still_running()
17 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 110, in assert_process_still_running
18 raise WebDriverException(
19selenium.common.exceptions.WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64
20geckodriver: error: Found argument '--websocket-port' which wasn't expected, orisn't valid in this context
21
22USAGE:
23 geckodriver [FLAGS] [OPTIONS]
24
25For more information try --help
26selenium.common.exceptions.WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64
27geckodriver: error: Found argument '--websocket-port' which wasn't expected, orisn't valid in this context
28
...implies that the GeckoDriver was unable to initiate/spawn a new Browsing Context i.e. firefox session.
Your main issue is the incompatibility between the version of the binaries you are using as follows:
- Your Selenium Client version is 4.1.0.
- But your GeckoDriver version is 0.26.0.
As @ernstki
mentions in their comment:
You are running a geckodriver older than 0.30.0, and it is missing the
--websocket-port
option, which newer/new-ish versions of Selenium seem to depend on.
To put it in simple words, till the previous GeckoDriver release of v0.29.0 the --websocket-port
option wasn't in use, which is now mandatory with Selenium v4.0.1.
Further @whimboo
also confirmed in his comment:
As it has been manifested the problem here is not geckodriver but Selenium. As such you should create an issue on the Selenium repository instead, so that an option could be added to not always pass the --websocket-port argument. If that request gets denied you will have to use older releases of Selenium if testing with older geckodriver releases is really needed.
Solution
Ensure that:
- Selenium is upgraded to current levels Version 4.1.0.
- GeckoDriver is upgraded to GeckoDriver v0.30.0 level.
- Firefox is upgraded to current Firefox v96.0.2 levels.
FreeBSD versions
Incase you are using FreeBSD versions where the GeckoDriver versions are older, in those cases you have to downgrade Selenium to v3.x levels.
Commands (courtesy: Kurtibert):
Uninstall Selenium:
1pkg install python3 firefox geckodriver py38-pip
2pip install --upgrade pip
3setenv CRYPTOGRAPHY_DONT_BUILD_RUST 1
4pip install cryptography==3.4.7
5pip install selenium
6from selenium import webdriver
7from selenium.webdriver.firefox.options import Options
8options = Options()
9options.headless = True
10driver = webdriver.Firefox(options=options)
11Traceback (most recent call last):
12 File "<stdin>", line 1, in <module>
13 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/firefox/webdriver.py", line 174, in __init__
14 self.service.start()
15 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 98, in start
16 self.assert_process_still_running()
17 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 110, in assert_process_still_running
18 raise WebDriverException(
19selenium.common.exceptions.WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64
20geckodriver: error: Found argument '--websocket-port' which wasn't expected, orisn't valid in this context
21
22USAGE:
23 geckodriver [FLAGS] [OPTIONS]
24
25For more information try --help
26selenium.common.exceptions.WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64
27geckodriver: error: Found argument '--websocket-port' which wasn't expected, orisn't valid in this context
28pip3 uninstall selenium;
29
Install Selenium:
1pkg install python3 firefox geckodriver py38-pip
2pip install --upgrade pip
3setenv CRYPTOGRAPHY_DONT_BUILD_RUST 1
4pip install cryptography==3.4.7
5pip install selenium
6from selenium import webdriver
7from selenium.webdriver.firefox.options import Options
8options = Options()
9options.headless = True
10driver = webdriver.Firefox(options=options)
11Traceback (most recent call last):
12 File "<stdin>", line 1, in <module>
13 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/firefox/webdriver.py", line 174, in __init__
14 self.service.start()
15 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 98, in start
16 self.assert_process_still_running()
17 File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 110, in assert_process_still_running
18 raise WebDriverException(
19selenium.common.exceptions.WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64
20geckodriver: error: Found argument '--websocket-port' which wasn't expected, orisn't valid in this context
21
22USAGE:
23 geckodriver [FLAGS] [OPTIONS]
24
25For more information try --help
26selenium.common.exceptions.WebDriverException: Message: Service geckodriver unexpectedly exited. Status code was: 64
27geckodriver: error: Found argument '--websocket-port' which wasn't expected, orisn't valid in this context
28pip3 uninstall selenium;
29pip3 install 'selenium<4.0.0'
30
QUESTION
Crypto-js encryption and Python decryption using HKDF key
Asked 2022-Mar-28 at 11:29Based on the example provided here on how to establish a shared secret and derived key between JS (Crypto-JS) and Python, I can end up with the same shared secret and derived key on both ends.
However, when I try to encrypt as below, I cannot find a way to properly decrypt from Python. My understanding is that probably I am messing with the padding or salts and hashes.
1 const payload = "hello"
2 var iv = CryptoJS.enc.Utf8.parse("1020304050607080");
3
4 var test = CryptoJS.AES.encrypt(
5 payload,
6 derived_key,
7 {iv: iv, mode: CryptoJS.mode.CBC}
8 ).toString();
9
10 console.log(test)
11
Output "y+In4kriw0qy4lji6/x14g=="
Python (one of the attempts):
1 const payload = "hello"
2 var iv = CryptoJS.enc.Utf8.parse("1020304050607080");
3
4 var test = CryptoJS.AES.encrypt(
5 payload,
6 derived_key,
7 {iv: iv, mode: CryptoJS.mode.CBC}
8 ).toString();
9
10 console.log(test)
11from Crypto.Cipher import AES
12from Crypto.Util.Padding import pad,unpad
13
14iv = "1020304050607080"
15
16test_enc = "y+In4kriw0qy4lji6/x14g=="
17enc = base64.b64decode(test_enc)
18
19cipher = AES.new(derived_key, AES.MODE_CBC, iv.encode('utf-8'))
20
21print(base64.b64decode(cipher.decrypt(enc)))
22
23print(unpad(cipher.decrypt(enc),16))
24
Any guidance here would be greatly appreciated as I am stuck for quite some time.
(I have encryption working using a password, but struggling with HKDF).
EDIT:
Here is the full Python code:
1 const payload = "hello"
2 var iv = CryptoJS.enc.Utf8.parse("1020304050607080");
3
4 var test = CryptoJS.AES.encrypt(
5 payload,
6 derived_key,
7 {iv: iv, mode: CryptoJS.mode.CBC}
8 ).toString();
9
10 console.log(test)
11from Crypto.Cipher import AES
12from Crypto.Util.Padding import pad,unpad
13
14iv = "1020304050607080"
15
16test_enc = "y+In4kriw0qy4lji6/x14g=="
17enc = base64.b64decode(test_enc)
18
19cipher = AES.new(derived_key, AES.MODE_CBC, iv.encode('utf-8'))
20
21print(base64.b64decode(cipher.decrypt(enc)))
22
23print(unpad(cipher.decrypt(enc),16))
24from cryptography.hazmat.primitives.asymmetric import ec
25from cryptography.hazmat.primitives.kdf.hkdf import HKDF
26from cryptography.hazmat.primitives import hashes
27from cryptography.hazmat.primitives import serialization
28import base64
29
30
31from Crypto.Cipher import AES
32from Crypto.Util.Padding import pad,unpad
33
34
35def deriveKey():
36
37 server_pkcs8 = b'''-----BEGIN PRIVATE KEY-----
38MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBReGpDVmoVTzxNbJx6
39aL4L9z1EdB91eonAmAw7mKDocLfCJITXZPUAmM46c6AipTmhZANiAAR3t96P0ZhU
40jtW3rHkHpeGu4e+YT+ufMiMeanE/w8p+d9aCslvIbZyBBzeZ/266yqTUUoiYDzqv
41Hb5q8rz7vEgr3DG4XfHYpCqfE2nttQGK3emHKGnvY239AteZkdwMpcs=
42-----END PRIVATE KEY-----'''
43
44 client_x509 = b'''-----BEGIN PUBLIC KEY-----
45MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEm0xeyy3nVnYpOpx/CV/FnlNEdWUZaqtB
46AGf7flKxXEjmlSUjseYzCd566sLpNg56Gw6hcFx+rWTLGR4eDRWfmwlXhyUasuEg
47mb0BQf8XJLBdvadb9eFx2CP1yjBsiy8e
48-----END PUBLIC KEY-----'''
49
50 client_public_key = serialization.load_pem_public_key(client_x509)
51 server_private_key = serialization.load_pem_private_key(server_pkcs8, password=None)
52 shared_secret = server_private_key.exchange(ec.ECDH(), client_public_key)
53 print('Shared secret: ' + base64.b64encode(shared_secret).decode('utf8')) # Shared secret: xbU6oDHMTYj3O71liM5KEJof3/0P4HlHJ28k7qtdqU/36llCizIlOWXtj8v+IngF
54
55 salt_bytes = "12345678".encode('utf-8')
56 info_bytes = "abc".encode('utf-8')
57
58 derived_key = HKDF(
59 algorithm=hashes.SHA256(),
60 length=32,
61 salt=salt_bytes,
62 info=info_bytes,
63 ).derive(shared_secret)
64 print('Derived key: ' + base64.b64encode(derived_key).decode('utf8'))
65 return derived_key
66
67derived_key = deriveKey()
68iv = "1020304050607080"
69
70test_enc = "y+In4kriw0qy4lji6/x14g=="
71enc = base64.b64decode(test_enc)
72
73cipher = AES.new(derived_key, AES.MODE_CBC, iv.encode('utf-8'))
74
75print(base64.b64decode(cipher.decrypt(enc)))
76
77print(unpad(cipher.decrypt(enc),16))
78
ANSWER
Answered 2022-Mar-28 at 11:29The issue is that the key is not passed correctly in the CryptoJS code.
The posted Python code generates LefjQ2pEXmiy/nNZvEJ43i8hJuaAnzbA1Cbn1hOuAgA=
as Base64-encoded key. This must be imported in the CryptoJS code using the Base64 encoder:
1 const payload = "hello"
2 var iv = CryptoJS.enc.Utf8.parse("1020304050607080");
3
4 var test = CryptoJS.AES.encrypt(
5 payload,
6 derived_key,
7 {iv: iv, mode: CryptoJS.mode.CBC}
8 ).toString();
9
10 console.log(test)
11from Crypto.Cipher import AES
12from Crypto.Util.Padding import pad,unpad
13
14iv = "1020304050607080"
15
16test_enc = "y+In4kriw0qy4lji6/x14g=="
17enc = base64.b64decode(test_enc)
18
19cipher = AES.new(derived_key, AES.MODE_CBC, iv.encode('utf-8'))
20
21print(base64.b64decode(cipher.decrypt(enc)))
22
23print(unpad(cipher.decrypt(enc),16))
24from cryptography.hazmat.primitives.asymmetric import ec
25from cryptography.hazmat.primitives.kdf.hkdf import HKDF
26from cryptography.hazmat.primitives import hashes
27from cryptography.hazmat.primitives import serialization
28import base64
29
30
31from Crypto.Cipher import AES
32from Crypto.Util.Padding import pad,unpad
33
34
35def deriveKey():
36
37 server_pkcs8 = b'''-----BEGIN PRIVATE KEY-----
38MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBReGpDVmoVTzxNbJx6
39aL4L9z1EdB91eonAmAw7mKDocLfCJITXZPUAmM46c6AipTmhZANiAAR3t96P0ZhU
40jtW3rHkHpeGu4e+YT+ufMiMeanE/w8p+d9aCslvIbZyBBzeZ/266yqTUUoiYDzqv
41Hb5q8rz7vEgr3DG4XfHYpCqfE2nttQGK3emHKGnvY239AteZkdwMpcs=
42-----END PRIVATE KEY-----'''
43
44 client_x509 = b'''-----BEGIN PUBLIC KEY-----
45MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEm0xeyy3nVnYpOpx/CV/FnlNEdWUZaqtB
46AGf7flKxXEjmlSUjseYzCd566sLpNg56Gw6hcFx+rWTLGR4eDRWfmwlXhyUasuEg
47mb0BQf8XJLBdvadb9eFx2CP1yjBsiy8e
48-----END PUBLIC KEY-----'''
49
50 client_public_key = serialization.load_pem_public_key(client_x509)
51 server_private_key = serialization.load_pem_private_key(server_pkcs8, password=None)
52 shared_secret = server_private_key.exchange(ec.ECDH(), client_public_key)
53 print('Shared secret: ' + base64.b64encode(shared_secret).decode('utf8')) # Shared secret: xbU6oDHMTYj3O71liM5KEJof3/0P4HlHJ28k7qtdqU/36llCizIlOWXtj8v+IngF
54
55 salt_bytes = "12345678".encode('utf-8')
56 info_bytes = "abc".encode('utf-8')
57
58 derived_key = HKDF(
59 algorithm=hashes.SHA256(),
60 length=32,
61 salt=salt_bytes,
62 info=info_bytes,
63 ).derive(shared_secret)
64 print('Derived key: ' + base64.b64encode(derived_key).decode('utf8'))
65 return derived_key
66
67derived_key = deriveKey()
68iv = "1020304050607080"
69
70test_enc = "y+In4kriw0qy4lji6/x14g=="
71enc = base64.b64decode(test_enc)
72
73cipher = AES.new(derived_key, AES.MODE_CBC, iv.encode('utf-8'))
74
75print(base64.b64decode(cipher.decrypt(enc)))
76
77print(unpad(cipher.decrypt(enc),16))
78const payload = "hello"
79var derived_key = CryptoJS.enc.Base64.parse("LefjQ2pEXmiy/nNZvEJ43i8hJuaAnzbA1Cbn1hOuAgA=")
80var iv = CryptoJS.enc.Utf8.parse("1020304050607080");
81var test = CryptoJS.AES.encrypt(payload, derived_key, {iv: iv, mode: CryptoJS.mode.CBC}).toString();
82document.getElementById("ct").innerHTML = test; // bLdmGA+HLLyFEVtBEuCzVg==
1 const payload = "hello"
2 var iv = CryptoJS.enc.Utf8.parse("1020304050607080");
3
4 var test = CryptoJS.AES.encrypt(
5 payload,
6 derived_key,
7 {iv: iv, mode: CryptoJS.mode.CBC}
8 ).toString();
9
10 console.log(test)
11from Crypto.Cipher import AES
12from Crypto.Util.Padding import pad,unpad
13
14iv = "1020304050607080"
15
16test_enc = "y+In4kriw0qy4lji6/x14g=="
17enc = base64.b64decode(test_enc)
18
19cipher = AES.new(derived_key, AES.MODE_CBC, iv.encode('utf-8'))
20
21print(base64.b64decode(cipher.decrypt(enc)))
22
23print(unpad(cipher.decrypt(enc),16))
24from cryptography.hazmat.primitives.asymmetric import ec
25from cryptography.hazmat.primitives.kdf.hkdf import HKDF
26from cryptography.hazmat.primitives import hashes
27from cryptography.hazmat.primitives import serialization
28import base64
29
30
31from Crypto.Cipher import AES
32from Crypto.Util.Padding import pad,unpad
33
34
35def deriveKey():
36
37 server_pkcs8 = b'''-----BEGIN PRIVATE KEY-----
38MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBReGpDVmoVTzxNbJx6
39aL4L9z1EdB91eonAmAw7mKDocLfCJITXZPUAmM46c6AipTmhZANiAAR3t96P0ZhU
40jtW3rHkHpeGu4e+YT+ufMiMeanE/w8p+d9aCslvIbZyBBzeZ/266yqTUUoiYDzqv
41Hb5q8rz7vEgr3DG4XfHYpCqfE2nttQGK3emHKGnvY239AteZkdwMpcs=
42-----END PRIVATE KEY-----'''
43
44 client_x509 = b'''-----BEGIN PUBLIC KEY-----
45MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEm0xeyy3nVnYpOpx/CV/FnlNEdWUZaqtB
46AGf7flKxXEjmlSUjseYzCd566sLpNg56Gw6hcFx+rWTLGR4eDRWfmwlXhyUasuEg
47mb0BQf8XJLBdvadb9eFx2CP1yjBsiy8e
48-----END PUBLIC KEY-----'''
49
50 client_public_key = serialization.load_pem_public_key(client_x509)
51 server_private_key = serialization.load_pem_private_key(server_pkcs8, password=None)
52 shared_secret = server_private_key.exchange(ec.ECDH(), client_public_key)
53 print('Shared secret: ' + base64.b64encode(shared_secret).decode('utf8')) # Shared secret: xbU6oDHMTYj3O71liM5KEJof3/0P4HlHJ28k7qtdqU/36llCizIlOWXtj8v+IngF
54
55 salt_bytes = "12345678".encode('utf-8')
56 info_bytes = "abc".encode('utf-8')
57
58 derived_key = HKDF(
59 algorithm=hashes.SHA256(),
60 length=32,
61 salt=salt_bytes,
62 info=info_bytes,
63 ).derive(shared_secret)
64 print('Derived key: ' + base64.b64encode(derived_key).decode('utf8'))
65 return derived_key
66
67derived_key = deriveKey()
68iv = "1020304050607080"
69
70test_enc = "y+In4kriw0qy4lji6/x14g=="
71enc = base64.b64decode(test_enc)
72
73cipher = AES.new(derived_key, AES.MODE_CBC, iv.encode('utf-8'))
74
75print(base64.b64decode(cipher.decrypt(enc)))
76
77print(unpad(cipher.decrypt(enc),16))
78const payload = "hello"
79var derived_key = CryptoJS.enc.Base64.parse("LefjQ2pEXmiy/nNZvEJ43i8hJuaAnzbA1Cbn1hOuAgA=")
80var iv = CryptoJS.enc.Utf8.parse("1020304050607080");
81var test = CryptoJS.AES.encrypt(payload, derived_key, {iv: iv, mode: CryptoJS.mode.CBC}).toString();
82document.getElementById("ct").innerHTML = test; // bLdmGA+HLLyFEVtBEuCzVg==<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
83<p style="font-family:'Courier New', monospace;" id="ct"></p>
The hereby generated ciphertext bLdmGA+HLLyFEVtBEuCzVg==
can be decrypted with the Python code:
1 const payload = "hello"
2 var iv = CryptoJS.enc.Utf8.parse("1020304050607080");
3
4 var test = CryptoJS.AES.encrypt(
5 payload,
6 derived_key,
7 {iv: iv, mode: CryptoJS.mode.CBC}
8 ).toString();
9
10 console.log(test)
11from Crypto.Cipher import AES
12from Crypto.Util.Padding import pad,unpad
13
14iv = "1020304050607080"
15
16test_enc = "y+In4kriw0qy4lji6/x14g=="
17enc = base64.b64decode(test_enc)
18
19cipher = AES.new(derived_key, AES.MODE_CBC, iv.encode('utf-8'))
20
21print(base64.b64decode(cipher.decrypt(enc)))
22
23print(unpad(cipher.decrypt(enc),16))
24from cryptography.hazmat.primitives.asymmetric import ec
25from cryptography.hazmat.primitives.kdf.hkdf import HKDF
26from cryptography.hazmat.primitives import hashes
27from cryptography.hazmat.primitives import serialization
28import base64
29
30
31from Crypto.Cipher import AES
32from Crypto.Util.Padding import pad,unpad
33
34
35def deriveKey():
36
37 server_pkcs8 = b'''-----BEGIN PRIVATE KEY-----
38MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBReGpDVmoVTzxNbJx6
39aL4L9z1EdB91eonAmAw7mKDocLfCJITXZPUAmM46c6AipTmhZANiAAR3t96P0ZhU
40jtW3rHkHpeGu4e+YT+ufMiMeanE/w8p+d9aCslvIbZyBBzeZ/266yqTUUoiYDzqv
41Hb5q8rz7vEgr3DG4XfHYpCqfE2nttQGK3emHKGnvY239AteZkdwMpcs=
42-----END PRIVATE KEY-----'''
43
44 client_x509 = b'''-----BEGIN PUBLIC KEY-----
45MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEm0xeyy3nVnYpOpx/CV/FnlNEdWUZaqtB
46AGf7flKxXEjmlSUjseYzCd566sLpNg56Gw6hcFx+rWTLGR4eDRWfmwlXhyUasuEg
47mb0BQf8XJLBdvadb9eFx2CP1yjBsiy8e
48-----END PUBLIC KEY-----'''
49
50 client_public_key = serialization.load_pem_public_key(client_x509)
51 server_private_key = serialization.load_pem_private_key(server_pkcs8, password=None)
52 shared_secret = server_private_key.exchange(ec.ECDH(), client_public_key)
53 print('Shared secret: ' + base64.b64encode(shared_secret).decode('utf8')) # Shared secret: xbU6oDHMTYj3O71liM5KEJof3/0P4HlHJ28k7qtdqU/36llCizIlOWXtj8v+IngF
54
55 salt_bytes = "12345678".encode('utf-8')
56 info_bytes = "abc".encode('utf-8')
57
58 derived_key = HKDF(
59 algorithm=hashes.SHA256(),
60 length=32,
61 salt=salt_bytes,
62 info=info_bytes,
63 ).derive(shared_secret)
64 print('Derived key: ' + base64.b64encode(derived_key).decode('utf8'))
65 return derived_key
66
67derived_key = deriveKey()
68iv = "1020304050607080"
69
70test_enc = "y+In4kriw0qy4lji6/x14g=="
71enc = base64.b64decode(test_enc)
72
73cipher = AES.new(derived_key, AES.MODE_CBC, iv.encode('utf-8'))
74
75print(base64.b64decode(cipher.decrypt(enc)))
76
77print(unpad(cipher.decrypt(enc),16))
78const payload = "hello"
79var derived_key = CryptoJS.enc.Base64.parse("LefjQ2pEXmiy/nNZvEJ43i8hJuaAnzbA1Cbn1hOuAgA=")
80var iv = CryptoJS.enc.Utf8.parse("1020304050607080");
81var test = CryptoJS.AES.encrypt(payload, derived_key, {iv: iv, mode: CryptoJS.mode.CBC}).toString();
82document.getElementById("ct").innerHTML = test; // bLdmGA+HLLyFEVtBEuCzVg==<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
83<p style="font-family:'Courier New', monospace;" id="ct"></p>from Crypto.Cipher import AES
84from Crypto.Util.Padding import unpad
85import base64
86
87test_enc = "bLdmGA+HLLyFEVtBEuCzVg=="
88enc = base64.b64decode(test_enc)
89derived_key = base64.b64decode("LefjQ2pEXmiy/nNZvEJ43i8hJuaAnzbA1Cbn1hOuAgA=")
90iv = "1020304050607080"
91cipher = AES.new(derived_key, AES.MODE_CBC, iv.encode('utf-8'))
92print(unpad(cipher.decrypt(enc),16)) # b'hello'
93
Note that for security reasons, a static IV should not be used so that key/IV pairs are not repeated.
QUESTION
Poetry | AttributeError 'Link' object has no attribute 'name'
Asked 2022-Mar-23 at 10:22I want to install packages from poetry.lock
file; using poetry install
.
However, the majority of packages throw the exact same error, indicating a shared fundamental problem.
What is causing this? What is the standard fix?
Specification:
- Windows 10,
- Visual Studio Code,
- Python 3.8.10 & Poetry 1.1.11,
- Ubuntu Bash.
Terminal:
rm poetry.lock
poetry update
poetry install
1me@PF2DCSXD:/mnt/c/Users/user/Documents/GitHub/workers-python/workers/composite_key$ poetry update
2Updating dependencies
3Resolving dependencies... (217.2s)
4
5Writing lock file
6
7Package operations: 55 installs, 8 updates, 0 removals
8
9 • Updating pyparsing (3.0.4 -> 2.4.7)
10 • Updating pyyaml (5.4.1 -> 6.0)
11 • Installing arrow (1.2.1)
12 • Installing chardet (4.0.0)
13 • Updating itsdangerous (1.1.0 -> 2.0.1)
14 • Updating jinja2 (2.11.3 -> 3.0.2)
15 • Updating packaging (20.9 -> 21.2)
16 • Installing text-unidecode (1.3)
17 • Updating werkzeug (1.0.1 -> 2.0.2)
18 • Installing binaryornot (0.4.4)
19 • Installing bokeh (2.4.1): Failed
20
21 AttributeError
22
23 'Link' object has no attribute 'name'
24
25 at ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/poetry/installation/executor.py:632 in _download_link
26 628│ raise RuntimeError(
27 629│ "Invalid hashes ({}) for {} using archive {}. Expected one of {}.".format(
28 630│ ", ".join(sorted(archive_hashes)),
29 631│ package,
30 → 632│ archive.name,
31 633│ ", ".join(sorted(hashes)),
32 634│ )
33 635│ )
34 636│
35
36 • Updating flask (1.1.4 -> 2.0.2)
37 • Installing jinja2-time (0.2.0)
38 • Installing poyo (0.5.0)
39 • Installing python-slugify (5.0.2)
40me@PF2DCSXD:/mnt/c/Users/user/Documents/GitHub/workers-python/workers/composite_key$ ls
41Dockerfile azure-pipeline-composite_key.yaml compositekey docs poetry.lock pyproject.toml
42me@PF2DCSXD:/mnt/c/Users/user/Documents/GitHub/workers-python/workers/composite_key$ poetry install
43Installing dependencies from lock file
44
45Package operations: 48 installs, 1 update, 3 removals
46
47 • Removing cffi (1.15.0)
48 • Removing colorama (0.4.4)
49 • Removing pycparser (2.20)
50 • Installing bokeh (2.4.1): Failed
51
52 AttributeError
53
54 'Link' object has no attribute 'name'
55
56 at ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/poetry/installation/executor.py:632 in _download_link
57 628│ raise RuntimeError(
58 629│ "Invalid hashes ({}) for {} using archive {}. Expected one of {}.".format(
59 630│ ", ".join(sorted(archive_hashes)),
60 631│ package,
61 → 632│ archive.name,
62 633│ ", ".join(sorted(hashes)),
63 634│ )
64 635│ )
65 636│
66
Suggested Solution Failed:
1me@PF2DCSXD:/mnt/c/Users/user/Documents/GitHub/workers-python/workers/composite_key$ poetry update
2Updating dependencies
3Resolving dependencies... (217.2s)
4
5Writing lock file
6
7Package operations: 55 installs, 8 updates, 0 removals
8
9 • Updating pyparsing (3.0.4 -> 2.4.7)
10 • Updating pyyaml (5.4.1 -> 6.0)
11 • Installing arrow (1.2.1)
12 • Installing chardet (4.0.0)
13 • Updating itsdangerous (1.1.0 -> 2.0.1)
14 • Updating jinja2 (2.11.3 -> 3.0.2)
15 • Updating packaging (20.9 -> 21.2)
16 • Installing text-unidecode (1.3)
17 • Updating werkzeug (1.0.1 -> 2.0.2)
18 • Installing binaryornot (0.4.4)
19 • Installing bokeh (2.4.1): Failed
20
21 AttributeError
22
23 'Link' object has no attribute 'name'
24
25 at ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/poetry/installation/executor.py:632 in _download_link
26 628│ raise RuntimeError(
27 629│ "Invalid hashes ({}) for {} using archive {}. Expected one of {}.".format(
28 630│ ", ".join(sorted(archive_hashes)),
29 631│ package,
30 → 632│ archive.name,
31 633│ ", ".join(sorted(hashes)),
32 634│ )
33 635│ )
34 636│
35
36 • Updating flask (1.1.4 -> 2.0.2)
37 • Installing jinja2-time (0.2.0)
38 • Installing poyo (0.5.0)
39 • Installing python-slugify (5.0.2)
40me@PF2DCSXD:/mnt/c/Users/user/Documents/GitHub/workers-python/workers/composite_key$ ls
41Dockerfile azure-pipeline-composite_key.yaml compositekey docs poetry.lock pyproject.toml
42me@PF2DCSXD:/mnt/c/Users/user/Documents/GitHub/workers-python/workers/composite_key$ poetry install
43Installing dependencies from lock file
44
45Package operations: 48 installs, 1 update, 3 removals
46
47 • Removing cffi (1.15.0)
48 • Removing colorama (0.4.4)
49 • Removing pycparser (2.20)
50 • Installing bokeh (2.4.1): Failed
51
52 AttributeError
53
54 'Link' object has no attribute 'name'
55
56 at ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/poetry/installation/executor.py:632 in _download_link
57 628│ raise RuntimeError(
58 629│ "Invalid hashes ({}) for {} using archive {}. Expected one of {}.".format(
59 630│ ", ".join(sorted(archive_hashes)),
60 631│ package,
61 → 632│ archive.name,
62 633│ ", ".join(sorted(hashes)),
63 634│ )
64 635│ )
65 636│
66danielbellhv@PF2DCSXD:/mnt/c/Users/dabell/Documents/GitHub/workers-python/workers/data_simulator$ pip install poetry==1.1.7
67Defaulting to user installation because normal site-packages is not writeable
68Collecting poetry==1.1.7
69 Downloading poetry-1.1.7-py2.py3-none-any.whl (173 kB)
70 |████████████████████████████████| 173 kB 622 kB/s
71Requirement already satisfied: cachy<0.4.0,>=0.3.0 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (0.3.0)
72Requirement already satisfied: requests-toolbelt<0.10.0,>=0.9.1 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (0.9.1)
73Requirement already satisfied: pkginfo<2.0,>=1.4 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (1.7.1)
74Requirement already satisfied: shellingham<2.0,>=1.1 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (1.4.0)
75Requirement already satisfied: tomlkit<1.0.0,>=0.7.0 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (0.7.2)
76Requirement already satisfied: cachecontrol[filecache]<0.13.0,>=0.12.4 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (0.12.8)
77Requirement already satisfied: html5lib<2.0,>=1.0 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (1.1)
78Requirement already satisfied: poetry-core<1.1.0,>=1.0.3 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (1.0.4)
79Requirement already satisfied: crashtest<0.4.0,>=0.3.0 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (0.3.1)
80Requirement already satisfied: clikit<0.7.0,>=0.6.2 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (0.6.2)
81Requirement already satisfied: keyring<22.0.0,>=21.2.0 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (21.8.0)
82Requirement already satisfied: pexpect<5.0.0,>=4.7.0 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (4.8.0)
83Requirement already satisfied: cleo<0.9.0,>=0.8.1 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (0.8.1)
84Requirement already satisfied: virtualenv<21.0.0,>=20.0.26 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (20.10.0)
85Requirement already satisfied: packaging<21.0,>=20.4 in /home/danielbellhv/.local/lib/python3.8/site-packages (from poetry==1.1.7) (20.9)
86Requirement already satisfied: requests<3.0,>=2.18 in /usr/lib/python3/dist-packages (from poetry==1.1.7) (2.22.0)
87Requirement already satisfied: msgpack>=0.5.2 in /home/danielbellhv/.local/lib/python3.8/site-packages (from cachecontrol[filecache]<0.13.0,>=0.12.4->poetry==1.1.7) (1.0.2)
88Requirement already satisfied: lockfile>=0.9 in /home/danielbellhv/.local/lib/python3.8/site-packages (from cachecontrol[filecache]<0.13.0,>=0.12.4->poetry==1.1.7) (0.12.2)
89Requirement already satisfied: pastel<0.3.0,>=0.2.0 in /home/danielbellhv/.local/lib/python3.8/site-packages (from clikit<0.7.0,>=0.6.2->poetry==1.1.7) (0.2.1)
90Requirement already satisfied: pylev<2.0,>=1.3 in /home/danielbellhv/.local/lib/python3.8/site-packages (from clikit<0.7.0,>=0.6.2->poetry==1.1.7) (1.4.0)
91Requirement already satisfied: webencodings in /home/danielbellhv/.local/lib/python3.8/site-packages (from html5lib<2.0,>=1.0->poetry==1.1.7) (0.5.1)
92Requirement already satisfied: six>=1.9 in /usr/lib/python3/dist-packages (from html5lib<2.0,>=1.0->poetry==1.1.7) (1.14.0)
93Requirement already satisfied: jeepney>=0.4.2 in /home/danielbellhv/.local/lib/python3.8/site-packages (from keyring<22.0.0,>=21.2.0->poetry==1.1.7) (0.7.1)
94Requirement already satisfied: SecretStorage>=3.2 in /home/danielbellhv/.local/lib/python3.8/site-packages (from keyring<22.0.0,>=21.2.0->poetry==1.1.7) (3.3.1)
95Requirement already satisfied: pyparsing>=2.0.2 in /home/danielbellhv/.local/lib/python3.8/site-packages (from packaging<21.0,>=20.4->poetry==1.1.7) (2.4.7)
96Requirement already satisfied: ptyprocess>=0.5 in /home/danielbellhv/.local/lib/python3.8/site-packages (from pexpect<5.0.0,>=4.7.0->poetry==1.1.7) (0.7.0)
97Requirement already satisfied: platformdirs<3,>=2 in /home/danielbellhv/.local/lib/python3.8/site-packages (from virtualenv<21.0.0,>=20.0.26->poetry==1.1.7) (2.4.0)
98Requirement already satisfied: distlib<1,>=0.3.1 in /home/danielbellhv/.local/lib/python3.8/site-packages (from virtualenv<21.0.0,>=20.0.26->poetry==1.1.7) (0.3.3)
99Requirement already satisfied: filelock<4,>=3.2 in /home/danielbellhv/.local/lib/python3.8/site-packages (from virtualenv<21.0.0,>=20.0.26->poetry==1.1.7) (3.3.2)
100Requirement already satisfied: backports.entry-points-selectable>=1.0.4 in /home/danielbellhv/.local/lib/python3.8/site-packages (from virtualenv<21.0.0,>=20.0.26->poetry==1.1.7) (1.1.0)
101Requirement already satisfied: cryptography>=2.0 in /usr/lib/python3/dist-packages (from SecretStorage>=3.2->keyring<22.0.0,>=21.2.0->poetry==1.1.7) (2.8)
102Installing collected packages: poetry
103Successfully installed poetry-1.1.7
104danielbellhv@PF2DCSXD:/mnt/c/Users/dabell/Documents/GitHub/workers-python/workers/data_simulator$ pip install poetry-core==1.0.4
105Defaulting to user installation because normal site-packages is not writeable
106Requirement already satisfied: poetry-core==1.0.4 in /home/danielbellhv/.local/lib/python3.8/site-packages (1.0.4)
107danielbellhv@PF2DCSXD:/mnt/c/Users/dabell/Documents/GitHub/workers-python/workers/data_simulator$ poetry install
108Installing dependencies from lock file
109
110Package operations: 82 installs, 0 updates, 0 removals
111
112 • Installing certifi (2021.5.30): Pending...
113 • Installing charset-normalizer (2.0.3): Failed
114
115 JSONDecodeError
116
117 Expecting value: line 1 column 1 (char 0)
118
119 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
120 396│ if ord0 == 0xfeff:
121 397│ idx += 1
122 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
123 399│ idx += 3
124 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
125 401│
126
127 • Installing idna (3.2): Failed
128
129 JSONDecodeError
130
131 Expecting value: line 1 column 1 (char 0)
132
133 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
134 396│ if ord0 == 0xfeff:
135 397│ idx += 1
136 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
137 399│ idx += 3
138 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
139 401│
140
141 • Installing pyasn1 (0.4.8): Failed
142
143 JSONDecodeError
144
145 Expecting value: line 1 column 1 (char 0)
146
147 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
148 396│ if ord0 == 0xfeff:
149 397│ idx += 1
150 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
151 399│ idx += 3
152 • Installing charset-normalizer (2.0.3): Failed
153
154 JSONDecodeError
155
156 Expecting value: line 1 column 1 (char 0)
157
158 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
159 396│ if ord0 == 0xfeff:
160 397│ idx += 1
161 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
162 399│ idx += 3
163 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
164 401│
165
166 • Installing idna (3.2): Failed
167
168 JSONDecodeError
169
170 Expecting value: line 1 column 1 (char 0)
171
172 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
173 396│ if ord0 == 0xfeff:
174 397│ idx += 1
175 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
176 399│ idx += 3
177 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
178 401│
179
180 • Installing pyasn1 (0.4.8): Failed
181
182 JSONDecodeError
183
184 Expecting value: line 1 column 1 (char 0)
185
186 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
187 396│ if ord0 == 0xfeff:
188 397│ idx += 1
189 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
190 399│ idx += 3
191 • Installing certifi (2021.5.30): Failed
192 • Installing charset-normalizer (2.0.3): Failed
193
194 JSONDecodeError
195
196 Expecting value: line 1 column 1 (char 0)
197
198 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
199 396│ if ord0 == 0xfeff:
200 397│ idx += 1
201 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
202 399│ idx += 3
203 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
204 401│
205
206 • Installing idna (3.2): Failed
207
208 JSONDecodeError
209
210 Expecting value: line 1 column 1 (char 0)
211
212 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
213 396│ if ord0 == 0xfeff:
214 397│ idx += 1
215 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
216 399│ idx += 3
217 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
218 401│
219
220 • Installing pyasn1 (0.4.8): Failed
221
222 JSONDecodeError
223
224 Expecting value: line 1 column 1 (char 0)
225
226 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
227 396│ if ord0 == 0xfeff:
228 397│ idx += 1
229 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
230 399│ idx += 3
231
232 • Installing charset-normalizer (2.0.3): Failed
233
234 JSONDecodeError
235
236 Expecting value: line 1 column 1 (char 0)
237
238 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
239 396│ if ord0 == 0xfeff:
240 397│ idx += 1
241 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
242 399│ idx += 3
243 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
244 401│
245
246 • Installing idna (3.2): Failed
247
248 JSONDecodeError
249
250 Expecting value: line 1 column 1 (char 0)
251
252 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
253 396│ if ord0 == 0xfeff:
254 397│ idx += 1
255 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
256 399│ idx += 3
257 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
258 401│
259
260 • Installing pyasn1 (0.4.8): Failed
261
262 JSONDecodeError
263
264 Expecting value: line 1 column 1 (char 0)
265
266 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
267 396│ if ord0 == 0xfeff:
268 397│ idx += 1
269 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
270 399│ idx += 3
271 JSONDecodeError
272 • Installing charset-normalizer (2.0.3): Failed
273
274 JSONDecodeError
275
276 Expecting value: line 1 column 1 (char 0)
277
278 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
279 396│ if ord0 == 0xfeff:
280 397│ idx += 1
281 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
282 399│ idx += 3
283 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
284 401│
285
286 • Installing idna (3.2): Failed
287
288 JSONDecodeError
289
290 Expecting value: line 1 column 1 (char 0)
291
292 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
293 396│ if ord0 == 0xfeff:
294 397│ idx += 1
295 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
296 399│ idx += 3
297 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
298 401│
299
300 • Installing pyasn1 (0.4.8): Failed
301
302 JSONDecodeError
303
304 Expecting value: line 1 column 1 (char 0)
305
306 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
307 396│ if ord0 == 0xfeff:
308 397│ idx += 1
309 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
310 399│ idx += 3
311
312 • Installing charset-normalizer (2.0.3): Failed
313
314 JSONDecodeError
315
316 Expecting value: line 1 column 1 (char 0)
317
318 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
319 396│ if ord0 == 0xfeff:
320 397│ idx += 1
321 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
322 399│ idx += 3
323 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
324 401│
325
326 • Installing idna (3.2): Failed
327
328 JSONDecodeError
329
330 Expecting value: line 1 column 1 (char 0)
331
332 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
333 396│ if ord0 == 0xfeff:
334 397│ idx += 1
335 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
336 399│ idx += 3
337 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
338 401│
339
340 • Installing pyasn1 (0.4.8): Failed
341
342 JSONDecodeError
343
344 Expecting value: line 1 column 1 (char 0)
345
346 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
347 396│ if ord0 == 0xfeff:
348 397│ idx += 1
349 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
350 399│ idx += 3
351 Expecting value: line 1 column 1 (char 0)
352 • Installing charset-normalizer (2.0.3): Failed
353
354 JSONDecodeError
355
356 Expecting value: line 1 column 1 (char 0)
357
358 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
359 396│ if ord0 == 0xfeff:
360 397│ idx += 1
361 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
362 399│ idx += 3
363 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
364 401│
365
366 • Installing idna (3.2): Failed
367
368 JSONDecodeError
369
370 Expecting value: line 1 column 1 (char 0)
371
372 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
373 396│ if ord0 == 0xfeff:
374 397│ idx += 1
375 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
376 399│ idx += 3
377 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
378 401│
379
380 • Installing pyasn1 (0.4.8): Failed
381
382 JSONDecodeError
383
384 Expecting value: line 1 column 1 (char 0)
385
386 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
387 396│ if ord0 == 0xfeff:
388 397│ idx += 1
389 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
390 399│ idx += 3
391
392 • Installing charset-normalizer (2.0.3): Failed
393
394 JSONDecodeError
395
396 Expecting value: line 1 column 1 (char 0)
397
398 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
399 396│ if ord0 == 0xfeff:
400 397│ idx += 1
401 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
402 399│ idx += 3
403 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
404 401│
405
406 • Installing idna (3.2): Failed
407
408 JSONDecodeError
409
410 Expecting value: line 1 column 1 (char 0)
411
412 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
413 396│ if ord0 == 0xfeff:
414 397│ idx += 1
415 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
416 399│ idx += 3
417 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
418 401│
419
420 • Installing pyasn1 (0.4.8): Failed
421
422 JSONDecodeError
423
424 Expecting value: line 1 column 1 (char 0)
425
426 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
427 396│ if ord0 == 0xfeff:
428 397│ idx += 1
429 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
430 399│ idx += 3
431 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
432 • Installing charset-normalizer (2.0.3): Failed
433
434 JSONDecodeError
435
436 Expecting value: line 1 column 1 (char 0)
437
438 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
439 396│ if ord0 == 0xfeff:
440 397│ idx += 1
441 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
442 399│ idx += 3
443 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
444 401│
445
446 • Installing idna (3.2): Failed
447
448 JSONDecodeError
449
450 Expecting value: line 1 column 1 (char 0)
451
452 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
453 396│ if ord0 == 0xfeff:
454 397│ idx += 1
455 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
456 399│ idx += 3
457 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
458 401│
459
460 • Installing pyasn1 (0.4.8): Failed
461
462 JSONDecodeError
463
464 Expecting value: line 1 column 1 (char 0)
465
466 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
467 396│ if ord0 == 0xfeff:
468 397│ idx += 1
469 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
470 399│ idx += 3
471 396│ if ord0 == 0xfeff:
472 • Installing charset-normalizer (2.0.3): Failed
473
474 JSONDecodeError
475
476 Expecting value: line 1 column 1 (char 0)
477
478 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
479 396│ if ord0 == 0xfeff:
480 397│ idx += 1
481 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
482 399│ idx += 3
483 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
484 401│
485
486 • Installing idna (3.2): Failed
487
488 JSONDecodeError
489
490 Expecting value: line 1 column 1 (char 0)
491
492 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
493 396│ if ord0 == 0xfeff:
494 397│ idx += 1
495 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
496 399│ idx += 3
497 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
498 401│
499
500 • Installing pyasn1 (0.4.8): Failed
501
502 JSONDecodeError
503
504 Expecting value: line 1 column 1 (char 0)
505
506 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
507 396│ if ord0 == 0xfeff:
508 397│ idx += 1
509 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
510 399│ idx += 3
511 397│ idx += 1
512 • Installing charset-normalizer (2.0.3): Failed
513
514 JSONDecodeError
515
516 Expecting value: line 1 column 1 (char 0)
517
518 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
519 396│ if ord0 == 0xfeff:
520 397│ idx += 1
521 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
522 399│ idx += 3
523 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
524 401│
525
526 • Installing idna (3.2): Failed
527
528 JSONDecodeError
529
530 Expecting value: line 1 column 1 (char 0)
531
532 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
533 396│ if ord0 == 0xfeff:
534 397│ idx += 1
535 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
536 399│ idx += 3
537 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
538 401│
539
540 • Installing pyasn1 (0.4.8): Failed
541
542 JSONDecodeError
543
544 Expecting value: line 1 column 1 (char 0)
545
546 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
547 396│ if ord0 == 0xfeff:
548 397│ idx += 1
549 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
550 399│ idx += 3
551 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
552 • Installing charset-normalizer (2.0.3): Failed
553
554 JSONDecodeError
555
556 Expecting value: line 1 column 1 (char 0)
557
558 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
559 396│ if ord0 == 0xfeff:
560 397│ idx += 1
561 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
562 399│ idx += 3
563 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
564 401│
565
566 • Installing idna (3.2): Failed
567
568 JSONDecodeError
569
570 Expecting value: line 1 column 1 (char 0)
571
572 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
573 396│ if ord0 == 0xfeff:
574 397│ idx += 1
575 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
576 399│ idx += 3
577 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
578 401│
579
580 • Installing pyasn1 (0.4.8): Failed
581
582 JSONDecodeError
583
584 Expecting value: line 1 column 1 (char 0)
585
586 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
587 396│ if ord0 == 0xfeff:
588 397│ idx += 1
589 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
590 399│ idx += 3
591 399│ idx += 3
592 • Installing charset-normalizer (2.0.3): Failed
593
594 JSONDecodeError
595
596 Expecting value: line 1 column 1 (char 0)
597
598 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
599 396│ if ord0 == 0xfeff:
600 397│ idx += 1
601 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
602 399│ idx += 3
603 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
604 401│
605
606 • Installing idna (3.2): Failed
607
608 JSONDecodeError
609
610 Expecting value: line 1 column 1 (char 0)
611
612 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
613 396│ if ord0 == 0xfeff:
614 397│ idx += 1
615 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
616 399│ idx += 3
617 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
618 401│
619
620 • Installing pyasn1 (0.4.8): Failed
621
622 JSONDecodeError
623
624 Expecting value: line 1 column 1 (char 0)
625
626 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
627 396│ if ord0 == 0xfeff:
628 397│ idx += 1
629 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
630 399│ idx += 3
631 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
632 • Installing charset-normalizer (2.0.3): Failed
633
634 JSONDecodeError
635
636 Expecting value: line 1 column 1 (char 0)
637
638 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
639 396│ if ord0 == 0xfeff:
640 397│ idx += 1
641 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
642 399│ idx += 3
643 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
644 401│
645
646 • Installing idna (3.2): Failed
647
648 JSONDecodeError
649
650 Expecting value: line 1 column 1 (char 0)
651
652 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
653 396│ if ord0 == 0xfeff:
654 397│ idx += 1
655 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
656 399│ idx += 3
657 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
658 401│
659
660 • Installing pyasn1 (0.4.8): Failed
661
662 JSONDecodeError
663
664 Expecting value: line 1 column 1 (char 0)
665
666 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
667 396│ if ord0 == 0xfeff:
668 397│ idx += 1
669 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
670 399│ idx += 3
671 401│
672 • Installing charset-normalizer (2.0.3): Failed
673
674 JSONDecodeError
675
676 Expecting value: line 1 column 1 (char 0)
677
678 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
679 396│ if ord0 == 0xfeff:
680 397│ idx += 1
681 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
682 399│ idx += 3
683 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
684 401│
685
686 • Installing idna (3.2): Failed
687
688 JSONDecodeError
689
690 Expecting value: line 1 column 1 (char 0)
691
692 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
693 396│ if ord0 == 0xfeff:
694 397│ idx += 1
695 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
696 399│ idx += 3
697 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
698 401│
699
700 • Installing pyasn1 (0.4.8): Failed
701
702 JSONDecodeError
703
704 Expecting value: line 1 column 1 (char 0)
705
706 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
707 396│ if ord0 == 0xfeff:
708 397│ idx += 1
709 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
710 399│ idx += 3
711
712 • Installing charset-normalizer (2.0.3): Failed
713
714 JSONDecodeError
715
716 Expecting value: line 1 column 1 (char 0)
717
718 at /usr/lib/python3/dist-packages/simplejson/decoder.py:400 in raw_decode
719 396│ if ord0 == 0xfeff:
720 397│ idx += 1
721 398│ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
722 399│ idx += 3
723 → 400│ return self.scan_once(s, idx=_w(s, idx).end())
724 401│
725
726 • Installing idna (3.2): Failed
727...
728
729 • Installing pyasn1 (0.4.8): Failed
730...
731
732 • Installing urllib3 (1.26.6): Failed
733...
734
Please let me know if there is anything else I can add to post.
ANSWER
Answered 2022-Mar-23 at 10:22This looks to be an active issue relating to poetry. See here - Issue #4085. Some suggest a workaround by downgrading poetry-core
down to 1.0.4.
There is an active PR to fix the issue.
QUESTION
Django mod_wsgi Apache Server, ModuleNotFoundError: No Module Named Django
Asked 2022-Feb-09 at 21:35I read ton of articles, but still can't figure out what I'm missing. I'm running a django website from virtualenv. Here's my config file. The website address is replaced by <domain.com>, can't use that here.
Config
1<VirtualHost *:80>
2
3 ServerAdmin sidharth@collaboration-management
4 ServerName <domain.com>
5 ServerAlias <domain.com>
6 DocumentRoot /home/sidharth/Downloads/gmcweb
7
8 ErrorLog ${APACHE_LOG_DIR}/error.log
9 CustomLog ${APACHE_LOG_DIR}/access.log combined
10
11 Alias /static /home/sidharth/Downloads/gmcweb/static
12
13 <Directory /home/sidharth/Downloads/gmcweb/static>
14 Require all granted
15 </Directory>
16
17 <Directory /home/sidharth/Downloads/gmcweb/gmcweb>
18 <Files wsgi.py>
19 Require all granted
20 </Files>
21 </Directory>
22
23
24 WSGIDaemonProcess gmcweb python-home=/home/sidharth/Downloads/gmcwebenvlin python-path=/home/sidharth/Downloads/gmcweb
25 WSGIProcessGroup gmcweb
26 WSGIScriptAlias / /home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py
27</VirtualHost>
28
Here's my WSGI.py file, didn't change anything never had to earlier
1<VirtualHost *:80>
2
3 ServerAdmin sidharth@collaboration-management
4 ServerName <domain.com>
5 ServerAlias <domain.com>
6 DocumentRoot /home/sidharth/Downloads/gmcweb
7
8 ErrorLog ${APACHE_LOG_DIR}/error.log
9 CustomLog ${APACHE_LOG_DIR}/access.log combined
10
11 Alias /static /home/sidharth/Downloads/gmcweb/static
12
13 <Directory /home/sidharth/Downloads/gmcweb/static>
14 Require all granted
15 </Directory>
16
17 <Directory /home/sidharth/Downloads/gmcweb/gmcweb>
18 <Files wsgi.py>
19 Require all granted
20 </Files>
21 </Directory>
22
23
24 WSGIDaemonProcess gmcweb python-home=/home/sidharth/Downloads/gmcwebenvlin python-path=/home/sidharth/Downloads/gmcweb
25 WSGIProcessGroup gmcweb
26 WSGIScriptAlias / /home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py
27</VirtualHost>
28import os
29
30from django.core.wsgi import get_wsgi_application
31
32os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'gmcweb.settings')
33
34application = get_wsgi_application()
35
Python Versions
My virtualenv python version is 3.9.5 Default Google VM python version is 3.6.9
Python Installed Libraries
1<VirtualHost *:80>
2
3 ServerAdmin sidharth@collaboration-management
4 ServerName <domain.com>
5 ServerAlias <domain.com>
6 DocumentRoot /home/sidharth/Downloads/gmcweb
7
8 ErrorLog ${APACHE_LOG_DIR}/error.log
9 CustomLog ${APACHE_LOG_DIR}/access.log combined
10
11 Alias /static /home/sidharth/Downloads/gmcweb/static
12
13 <Directory /home/sidharth/Downloads/gmcweb/static>
14 Require all granted
15 </Directory>
16
17 <Directory /home/sidharth/Downloads/gmcweb/gmcweb>
18 <Files wsgi.py>
19 Require all granted
20 </Files>
21 </Directory>
22
23
24 WSGIDaemonProcess gmcweb python-home=/home/sidharth/Downloads/gmcwebenvlin python-path=/home/sidharth/Downloads/gmcweb
25 WSGIProcessGroup gmcweb
26 WSGIScriptAlias / /home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py
27</VirtualHost>
28import os
29
30from django.core.wsgi import get_wsgi_application
31
32os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'gmcweb.settings')
33
34application = get_wsgi_application()
35Package Version
36------------------------ ---------
37asgiref 3.4.0
38attrs 21.2.0
39autopep8 1.5.7
40beautifulsoup4 4.9.3
41certifi 2021.5.30
42cffi 1.14.5
43chardet 4.0.0
44cryptography 3.4.7
45defusedxml 0.7.1
46Django 3.2.4
47django-allauth 0.44.0
48django-livereload-server 0.3.2
49idna 2.10
50jsonschema 3.2.0
51oauthlib 3.1.1
52pip 21.2.3
53pycodestyle 2.7.0
54pycparser 2.20
55PyJWT 2.1.0
56pyrsistent 0.18.0
57python3-openid 3.2.0
58pytz 2021.1
59requests 2.25.1
60requests-oauthlib 1.3.0
61setuptools 57.4.0
62six 1.16.0
63soupsieve 2.2.1
64sqlparse 0.4.1
65toml 0.10.2
66tornado 6.1
67urllib3 1.26.6
68
I installed apache modwsgi as well sudo apt-get install python3-pip apache2 libapache2-mod-wsgi-py3
Error Log File
1<VirtualHost *:80>
2
3 ServerAdmin sidharth@collaboration-management
4 ServerName <domain.com>
5 ServerAlias <domain.com>
6 DocumentRoot /home/sidharth/Downloads/gmcweb
7
8 ErrorLog ${APACHE_LOG_DIR}/error.log
9 CustomLog ${APACHE_LOG_DIR}/access.log combined
10
11 Alias /static /home/sidharth/Downloads/gmcweb/static
12
13 <Directory /home/sidharth/Downloads/gmcweb/static>
14 Require all granted
15 </Directory>
16
17 <Directory /home/sidharth/Downloads/gmcweb/gmcweb>
18 <Files wsgi.py>
19 Require all granted
20 </Files>
21 </Directory>
22
23
24 WSGIDaemonProcess gmcweb python-home=/home/sidharth/Downloads/gmcwebenvlin python-path=/home/sidharth/Downloads/gmcweb
25 WSGIProcessGroup gmcweb
26 WSGIScriptAlias / /home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py
27</VirtualHost>
28import os
29
30from django.core.wsgi import get_wsgi_application
31
32os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'gmcweb.settings')
33
34application = get_wsgi_application()
35Package Version
36------------------------ ---------
37asgiref 3.4.0
38attrs 21.2.0
39autopep8 1.5.7
40beautifulsoup4 4.9.3
41certifi 2021.5.30
42cffi 1.14.5
43chardet 4.0.0
44cryptography 3.4.7
45defusedxml 0.7.1
46Django 3.2.4
47django-allauth 0.44.0
48django-livereload-server 0.3.2
49idna 2.10
50jsonschema 3.2.0
51oauthlib 3.1.1
52pip 21.2.3
53pycodestyle 2.7.0
54pycparser 2.20
55PyJWT 2.1.0
56pyrsistent 0.18.0
57python3-openid 3.2.0
58pytz 2021.1
59requests 2.25.1
60requests-oauthlib 1.3.0
61setuptools 57.4.0
62six 1.16.0
63soupsieve 2.2.1
64sqlparse 0.4.1
65toml 0.10.2
66tornado 6.1
67urllib3 1.26.6
68[Thu Sep 23 15:05:06.554545 2021] [mpm_event:notice] [pid 32077:tid 140392561593280] AH00489: Apache/2.4.29 (Ubuntu) mod_wsgi/4.5.17 Python/3.6 configured -- resuming normal operations
69[Thu Sep 23 15:05:06.554594 2021] [core:notice] [pid 32077:tid 140392561593280] AH00094: Command line: '/usr/sbin/apache2'
70[Thu Sep 23 15:05:19.081581 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] mod_wsgi (pid=32617): Target WSGI script '/home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py' c$
71[Thu Sep 23 15:05:19.081638 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] mod_wsgi (pid=32617): Exception occurred processing WSGI script '/home/sidharth/Downloads/g$
72[Thu Sep 23 15:05:19.081828 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] Traceback (most recent call last):
73[Thu Sep 23 15:05:19.081849 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] File "/home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py", line 12, in <module>
74[Thu Sep 23 15:05:19.081853 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] from django.core.wsgi import get_wsgi_application
75[Thu Sep 23 15:05:19.081867 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] ModuleNotFoundError: No module named 'django'
76[Thu Sep 23 15:05:32.244779 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] mod_wsgi (pid=32617): Target WSGI script '/home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py' c$
77[Thu Sep 23 15:05:32.244845 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] mod_wsgi (pid=32617): Exception occurred processing WSGI script '/home/sidharth/Downloads/g$
78[Thu Sep 23 15:05:32.244924 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] Traceback (most recent call last):
79[Thu Sep 23 15:05:32.244946 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] File "/home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py", line 12, in <module>
80[Thu Sep 23 15:05:32.244951 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] from django.core.wsgi import get_wsgi_application
81[Thu Sep 23 15:05:32.244966 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] ModuleNotFoundError: No module named 'django'
82
ANSWER
Answered 2021-Sep-23 at 15:28The error says that either you haven't got Django installed or didn't activate the virtual environment in which the Django was installed. Make sure that you check the list of installed packages and find Django in there, via:
1<VirtualHost *:80>
2
3 ServerAdmin sidharth@collaboration-management
4 ServerName <domain.com>
5 ServerAlias <domain.com>
6 DocumentRoot /home/sidharth/Downloads/gmcweb
7
8 ErrorLog ${APACHE_LOG_DIR}/error.log
9 CustomLog ${APACHE_LOG_DIR}/access.log combined
10
11 Alias /static /home/sidharth/Downloads/gmcweb/static
12
13 <Directory /home/sidharth/Downloads/gmcweb/static>
14 Require all granted
15 </Directory>
16
17 <Directory /home/sidharth/Downloads/gmcweb/gmcweb>
18 <Files wsgi.py>
19 Require all granted
20 </Files>
21 </Directory>
22
23
24 WSGIDaemonProcess gmcweb python-home=/home/sidharth/Downloads/gmcwebenvlin python-path=/home/sidharth/Downloads/gmcweb
25 WSGIProcessGroup gmcweb
26 WSGIScriptAlias / /home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py
27</VirtualHost>
28import os
29
30from django.core.wsgi import get_wsgi_application
31
32os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'gmcweb.settings')
33
34application = get_wsgi_application()
35Package Version
36------------------------ ---------
37asgiref 3.4.0
38attrs 21.2.0
39autopep8 1.5.7
40beautifulsoup4 4.9.3
41certifi 2021.5.30
42cffi 1.14.5
43chardet 4.0.0
44cryptography 3.4.7
45defusedxml 0.7.1
46Django 3.2.4
47django-allauth 0.44.0
48django-livereload-server 0.3.2
49idna 2.10
50jsonschema 3.2.0
51oauthlib 3.1.1
52pip 21.2.3
53pycodestyle 2.7.0
54pycparser 2.20
55PyJWT 2.1.0
56pyrsistent 0.18.0
57python3-openid 3.2.0
58pytz 2021.1
59requests 2.25.1
60requests-oauthlib 1.3.0
61setuptools 57.4.0
62six 1.16.0
63soupsieve 2.2.1
64sqlparse 0.4.1
65toml 0.10.2
66tornado 6.1
67urllib3 1.26.6
68[Thu Sep 23 15:05:06.554545 2021] [mpm_event:notice] [pid 32077:tid 140392561593280] AH00489: Apache/2.4.29 (Ubuntu) mod_wsgi/4.5.17 Python/3.6 configured -- resuming normal operations
69[Thu Sep 23 15:05:06.554594 2021] [core:notice] [pid 32077:tid 140392561593280] AH00094: Command line: '/usr/sbin/apache2'
70[Thu Sep 23 15:05:19.081581 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] mod_wsgi (pid=32617): Target WSGI script '/home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py' c$
71[Thu Sep 23 15:05:19.081638 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] mod_wsgi (pid=32617): Exception occurred processing WSGI script '/home/sidharth/Downloads/g$
72[Thu Sep 23 15:05:19.081828 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] Traceback (most recent call last):
73[Thu Sep 23 15:05:19.081849 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] File "/home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py", line 12, in <module>
74[Thu Sep 23 15:05:19.081853 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] from django.core.wsgi import get_wsgi_application
75[Thu Sep 23 15:05:19.081867 2021] [wsgi:error] [pid 32617:tid 140392409851648] [remote 103.206.177.13:49604] ModuleNotFoundError: No module named 'django'
76[Thu Sep 23 15:05:32.244779 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] mod_wsgi (pid=32617): Target WSGI script '/home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py' c$
77[Thu Sep 23 15:05:32.244845 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] mod_wsgi (pid=32617): Exception occurred processing WSGI script '/home/sidharth/Downloads/g$
78[Thu Sep 23 15:05:32.244924 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] Traceback (most recent call last):
79[Thu Sep 23 15:05:32.244946 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] File "/home/sidharth/Downloads/gmcweb/gmcweb/wsgi.py", line 12, in <module>
80[Thu Sep 23 15:05:32.244951 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] from django.core.wsgi import get_wsgi_application
81[Thu Sep 23 15:05:32.244966 2021] [wsgi:error] [pid 32617:tid 140392325842688] [remote 103.206.177.13:52916] ModuleNotFoundError: No module named 'django'
82$pip list
83
QUESTION
Encrypt data in Javascript, Decrypt data in C# using private/public keys
Asked 2022-Jan-26 at 13:22I want to encrypt data in a web browser that is send to my C# backend and decrypted there.
That fails because I am unable to decrypt the data generated on the frontend in the backend.
Here's what I did so far.
First I created a private/public key pair (in XmlString Format). I took the ExportPublicKey
function to generate the public key file from here: https://stackoverflow.com/a/28407693/98491
1private static void GeneratePrivatePublicKeyPair() {
2 var name = "test";
3 var privateKeyXmlFile = name + "_priv.xml";
4 var publicKeyXmlFile = name + "_pub.xml";
5 var publicKeyFile = name + ".pub";
6
7 using var provider = new RSACryptoServiceProvider(1024);
8 File.WriteAllText(privateKeyXmlFile, provider.ToXmlString(true));
9 File.WriteAllText(publicKeyXmlFile, provider.ToXmlString(false));
10 using var publicKeyWriter = File.CreateText(publicKeyFile);
11 ExportPublicKey(provider, publicKeyWriter);
12}
13
Now I can use the public key to encrypt data in my frontend.
1private static void GeneratePrivatePublicKeyPair() {
2 var name = "test";
3 var privateKeyXmlFile = name + "_priv.xml";
4 var publicKeyXmlFile = name + "_pub.xml";
5 var publicKeyFile = name + ".pub";
6
7 using var provider = new RSACryptoServiceProvider(1024);
8 File.WriteAllText(privateKeyXmlFile, provider.ToXmlString(true));
9 File.WriteAllText(publicKeyXmlFile, provider.ToXmlString(false));
10 using var publicKeyWriter = File.CreateText(publicKeyFile);
11 ExportPublicKey(provider, publicKeyWriter);
12}
13(() => {
14
15 const publicKey = `-----BEGIN PUBLIC KEY-----
16MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGy8btrbnSNPz7vWKfQXKxKXzg
1728ZD8jCAd7gGYfUIFqKqUcogHWt5gyGvTgEhwBwBP1kYrVnBlhB2nuWHLYpJDI6b
18uBoqKrHtrcdgXsKumSP0OKpn0nbYxknOvNYVjUUR6plMboUBaWX1oKoR6pNzTEHS
19al4bIU7XMwppkR3KNQIDAQAB
20-----END PUBLIC KEY-----`;
21
22 function getSpkiDer(spkiPem) {
23 const pemHeader = "-----BEGIN PUBLIC KEY-----";
24 const pemFooter = "-----END PUBLIC KEY-----";
25 var pemContents = spkiPem.substring(
26 pemHeader.length,
27 spkiPem.length - pemFooter.length
28 );
29 var binaryDerString = window.atob(pemContents);
30 return str2ab(binaryDerString);
31 }
32
33 async function importPublicKey(spkiPem) {
34 return await window.crypto.subtle.importKey(
35 "spki",
36 getSpkiDer(spkiPem),
37 {
38 name: "RSA-OAEP",
39 hash: "SHA-256",
40 },
41 true,
42 ["encrypt"]
43 );
44 }
45
46 async function encryptRSA(key, plaintext) {
47 let encrypted = await window.crypto.subtle.encrypt(
48 {
49 name: "RSA-OAEP",
50 },
51 key,
52 plaintext
53 );
54 return encrypted;
55 }
56
57 function str2ab(str) {
58 const buf = new ArrayBuffer(str.length);
59 const bufView = new Uint8Array(buf);
60 for (let i = 0, strLen = str.length; i < strLen; i++) {
61 bufView[i] = str.charCodeAt(i);
62 }
63 return buf;
64 }
65
66 function ab2str(buf) {
67 return String.fromCharCode.apply(null, new Uint8Array(buf));
68 }
69
70 async function encrypt(plaintext) {
71 const pub = await importPublicKey(publicKey);
72 const encrypted = await encryptRSA(
73 pub,
74 new TextEncoder().encode(plaintext)
75 );
76 const encryptedBase64 = window.btoa(ab2str(encrypted));
77 console.log(encryptedBase64);
78 }
79
80 encrypt("I want to decrypt this string in C#");
81
82 })();
However: If I want to decrypt the code in my backend again, this fails
1private static void GeneratePrivatePublicKeyPair() {
2 var name = "test";
3 var privateKeyXmlFile = name + "_priv.xml";
4 var publicKeyXmlFile = name + "_pub.xml";
5 var publicKeyFile = name + ".pub";
6
7 using var provider = new RSACryptoServiceProvider(1024);
8 File.WriteAllText(privateKeyXmlFile, provider.ToXmlString(true));
9 File.WriteAllText(publicKeyXmlFile, provider.ToXmlString(false));
10 using var publicKeyWriter = File.CreateText(publicKeyFile);
11 ExportPublicKey(provider, publicKeyWriter);
12}
13(() => {
14
15 const publicKey = `-----BEGIN PUBLIC KEY-----
16MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGy8btrbnSNPz7vWKfQXKxKXzg
1728ZD8jCAd7gGYfUIFqKqUcogHWt5gyGvTgEhwBwBP1kYrVnBlhB2nuWHLYpJDI6b
18uBoqKrHtrcdgXsKumSP0OKpn0nbYxknOvNYVjUUR6plMboUBaWX1oKoR6pNzTEHS
19al4bIU7XMwppkR3KNQIDAQAB
20-----END PUBLIC KEY-----`;
21
22 function getSpkiDer(spkiPem) {
23 const pemHeader = "-----BEGIN PUBLIC KEY-----";
24 const pemFooter = "-----END PUBLIC KEY-----";
25 var pemContents = spkiPem.substring(
26 pemHeader.length,
27 spkiPem.length - pemFooter.length
28 );
29 var binaryDerString = window.atob(pemContents);
30 return str2ab(binaryDerString);
31 }
32
33 async function importPublicKey(spkiPem) {
34 return await window.crypto.subtle.importKey(
35 "spki",
36 getSpkiDer(spkiPem),
37 {
38 name: "RSA-OAEP",
39 hash: "SHA-256",
40 },
41 true,
42 ["encrypt"]
43 );
44 }
45
46 async function encryptRSA(key, plaintext) {
47 let encrypted = await window.crypto.subtle.encrypt(
48 {
49 name: "RSA-OAEP",
50 },
51 key,
52 plaintext
53 );
54 return encrypted;
55 }
56
57 function str2ab(str) {
58 const buf = new ArrayBuffer(str.length);
59 const bufView = new Uint8Array(buf);
60 for (let i = 0, strLen = str.length; i < strLen; i++) {
61 bufView[i] = str.charCodeAt(i);
62 }
63 return buf;
64 }
65
66 function ab2str(buf) {
67 return String.fromCharCode.apply(null, new Uint8Array(buf));
68 }
69
70 async function encrypt(plaintext) {
71 const pub = await importPublicKey(publicKey);
72 const encrypted = await encryptRSA(
73 pub,
74 new TextEncoder().encode(plaintext)
75 );
76 const encryptedBase64 = window.btoa(ab2str(encrypted));
77 console.log(encryptedBase64);
78 }
79
80 encrypt("I want to decrypt this string in C#");
81
82 })();private static void Decrypt()
83{
84 var name = "test";
85 var encryptedBase64 = @"Rzabx5380rkx2+KKB+HaJP2dOXDcOC7SkYOy4HN8+Nb9HmjqeZfGQlf+ZUa6uAfAJ3oAB2iIlHlnx+iXK3XDIX3izjoW1eeiNmdOWieNCu6YXqW4denUVEv0Z4EpAmEYgVImnEzoMdmPDEcl9UHgdWUmS4Bnq6T8Yqh3UZ/4NOc=";
86 var encrypted = Convert.FromBase64String(encryptedBase64);
87 using var privateKey = new RSACryptoServiceProvider();
88 privateKey.FromXmlString(File.ReadAllText(name + "_priv.xml"));
89 var decryptedBytes = privateKey.Decrypt(encrypted, false);
90 var dectryptedText = Encoding.UTF8.GetString(decryptedBytes);
91}
92
I tried privateKey.Decrypt(encrypted, false);
which throws
1private static void GeneratePrivatePublicKeyPair() {
2 var name = "test";
3 var privateKeyXmlFile = name + "_priv.xml";
4 var publicKeyXmlFile = name + "_pub.xml";
5 var publicKeyFile = name + ".pub";
6
7 using var provider = new RSACryptoServiceProvider(1024);
8 File.WriteAllText(privateKeyXmlFile, provider.ToXmlString(true));
9 File.WriteAllText(publicKeyXmlFile, provider.ToXmlString(false));
10 using var publicKeyWriter = File.CreateText(publicKeyFile);
11 ExportPublicKey(provider, publicKeyWriter);
12}
13(() => {
14
15 const publicKey = `-----BEGIN PUBLIC KEY-----
16MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGy8btrbnSNPz7vWKfQXKxKXzg
1728ZD8jCAd7gGYfUIFqKqUcogHWt5gyGvTgEhwBwBP1kYrVnBlhB2nuWHLYpJDI6b
18uBoqKrHtrcdgXsKumSP0OKpn0nbYxknOvNYVjUUR6plMboUBaWX1oKoR6pNzTEHS
19al4bIU7XMwppkR3KNQIDAQAB
20-----END PUBLIC KEY-----`;
21
22 function getSpkiDer(spkiPem) {
23 const pemHeader = "-----BEGIN PUBLIC KEY-----";
24 const pemFooter = "-----END PUBLIC KEY-----";
25 var pemContents = spkiPem.substring(
26 pemHeader.length,
27 spkiPem.length - pemFooter.length
28 );
29 var binaryDerString = window.atob(pemContents);
30 return str2ab(binaryDerString);
31 }
32
33 async function importPublicKey(spkiPem) {
34 return await window.crypto.subtle.importKey(
35 "spki",
36 getSpkiDer(spkiPem),
37 {
38 name: "RSA-OAEP",
39 hash: "SHA-256",
40 },
41 true,
42 ["encrypt"]
43 );
44 }
45
46 async function encryptRSA(key, plaintext) {
47 let encrypted = await window.crypto.subtle.encrypt(
48 {
49 name: "RSA-OAEP",
50 },
51 key,
52 plaintext
53 );
54 return encrypted;
55 }
56
57 function str2ab(str) {
58 const buf = new ArrayBuffer(str.length);
59 const bufView = new Uint8Array(buf);
60 for (let i = 0, strLen = str.length; i < strLen; i++) {
61 bufView[i] = str.charCodeAt(i);
62 }
63 return buf;
64 }
65
66 function ab2str(buf) {
67 return String.fromCharCode.apply(null, new Uint8Array(buf));
68 }
69
70 async function encrypt(plaintext) {
71 const pub = await importPublicKey(publicKey);
72 const encrypted = await encryptRSA(
73 pub,
74 new TextEncoder().encode(plaintext)
75 );
76 const encryptedBase64 = window.btoa(ab2str(encrypted));
77 console.log(encryptedBase64);
78 }
79
80 encrypt("I want to decrypt this string in C#");
81
82 })();private static void Decrypt()
83{
84 var name = "test";
85 var encryptedBase64 = @"Rzabx5380rkx2+KKB+HaJP2dOXDcOC7SkYOy4HN8+Nb9HmjqeZfGQlf+ZUa6uAfAJ3oAB2iIlHlnx+iXK3XDIX3izjoW1eeiNmdOWieNCu6YXqW4denUVEv0Z4EpAmEYgVImnEzoMdmPDEcl9UHgdWUmS4Bnq6T8Yqh3UZ/4NOc=";
86 var encrypted = Convert.FromBase64String(encryptedBase64);
87 using var privateKey = new RSACryptoServiceProvider();
88 privateKey.FromXmlString(File.ReadAllText(name + "_priv.xml"));
89 var decryptedBytes = privateKey.Decrypt(encrypted, false);
90 var dectryptedText = Encoding.UTF8.GetString(decryptedBytes);
91}
92Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Wrong parameter
93 CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
94 RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
95
and privateKey.Decrypt(encrypted, false);
which throws
1private static void GeneratePrivatePublicKeyPair() {
2 var name = "test";
3 var privateKeyXmlFile = name + "_priv.xml";
4 var publicKeyXmlFile = name + "_pub.xml";
5 var publicKeyFile = name + ".pub";
6
7 using var provider = new RSACryptoServiceProvider(1024);
8 File.WriteAllText(privateKeyXmlFile, provider.ToXmlString(true));
9 File.WriteAllText(publicKeyXmlFile, provider.ToXmlString(false));
10 using var publicKeyWriter = File.CreateText(publicKeyFile);
11 ExportPublicKey(provider, publicKeyWriter);
12}
13(() => {
14
15 const publicKey = `-----BEGIN PUBLIC KEY-----
16MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGy8btrbnSNPz7vWKfQXKxKXzg
1728ZD8jCAd7gGYfUIFqKqUcogHWt5gyGvTgEhwBwBP1kYrVnBlhB2nuWHLYpJDI6b
18uBoqKrHtrcdgXsKumSP0OKpn0nbYxknOvNYVjUUR6plMboUBaWX1oKoR6pNzTEHS
19al4bIU7XMwppkR3KNQIDAQAB
20-----END PUBLIC KEY-----`;
21
22 function getSpkiDer(spkiPem) {
23 const pemHeader = "-----BEGIN PUBLIC KEY-----";
24 const pemFooter = "-----END PUBLIC KEY-----";
25 var pemContents = spkiPem.substring(
26 pemHeader.length,
27 spkiPem.length - pemFooter.length
28 );
29 var binaryDerString = window.atob(pemContents);
30 return str2ab(binaryDerString);
31 }
32
33 async function importPublicKey(spkiPem) {
34 return await window.crypto.subtle.importKey(
35 "spki",
36 getSpkiDer(spkiPem),
37 {
38 name: "RSA-OAEP",
39 hash: "SHA-256",
40 },
41 true,
42 ["encrypt"]
43 );
44 }
45
46 async function encryptRSA(key, plaintext) {
47 let encrypted = await window.crypto.subtle.encrypt(
48 {
49 name: "RSA-OAEP",
50 },
51 key,
52 plaintext
53 );
54 return encrypted;
55 }
56
57 function str2ab(str) {
58 const buf = new ArrayBuffer(str.length);
59 const bufView = new Uint8Array(buf);
60 for (let i = 0, strLen = str.length; i < strLen; i++) {
61 bufView[i] = str.charCodeAt(i);
62 }
63 return buf;
64 }
65
66 function ab2str(buf) {
67 return String.fromCharCode.apply(null, new Uint8Array(buf));
68 }
69
70 async function encrypt(plaintext) {
71 const pub = await importPublicKey(publicKey);
72 const encrypted = await encryptRSA(
73 pub,
74 new TextEncoder().encode(plaintext)
75 );
76 const encryptedBase64 = window.btoa(ab2str(encrypted));
77 console.log(encryptedBase64);
78 }
79
80 encrypt("I want to decrypt this string in C#");
81
82 })();private static void Decrypt()
83{
84 var name = "test";
85 var encryptedBase64 = @"Rzabx5380rkx2+KKB+HaJP2dOXDcOC7SkYOy4HN8+Nb9HmjqeZfGQlf+ZUa6uAfAJ3oAB2iIlHlnx+iXK3XDIX3izjoW1eeiNmdOWieNCu6YXqW4denUVEv0Z4EpAmEYgVImnEzoMdmPDEcl9UHgdWUmS4Bnq6T8Yqh3UZ/4NOc=";
86 var encrypted = Convert.FromBase64String(encryptedBase64);
87 using var privateKey = new RSACryptoServiceProvider();
88 privateKey.FromXmlString(File.ReadAllText(name + "_priv.xml"));
89 var decryptedBytes = privateKey.Decrypt(encrypted, false);
90 var dectryptedText = Encoding.UTF8.GetString(decryptedBytes);
91}
92Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Wrong parameter
93 CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
94 RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
95System.Security.Cryptography.CryptographicException: Cryptography_OAEPDecoding,
96 CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
97 RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
98
Note: I verified that I can sucessfully encrypt/decrypt data in the backend with the private_key/public keys in xml format.
And I verified that I can sucessfully encrypt/decrypt data in the frontend with the
private/public keys in PEM format.
The thing that does not work is decrypt a string in C# that is encrypted in the frontend with javascript.
What am I doing wrong?
For reference (Just generated for this purpose)
private key1private static void GeneratePrivatePublicKeyPair() {
2 var name = "test";
3 var privateKeyXmlFile = name + "_priv.xml";
4 var publicKeyXmlFile = name + "_pub.xml";
5 var publicKeyFile = name + ".pub";
6
7 using var provider = new RSACryptoServiceProvider(1024);
8 File.WriteAllText(privateKeyXmlFile, provider.ToXmlString(true));
9 File.WriteAllText(publicKeyXmlFile, provider.ToXmlString(false));
10 using var publicKeyWriter = File.CreateText(publicKeyFile);
11 ExportPublicKey(provider, publicKeyWriter);
12}
13(() => {
14
15 const publicKey = `-----BEGIN PUBLIC KEY-----
16MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGy8btrbnSNPz7vWKfQXKxKXzg
1728ZD8jCAd7gGYfUIFqKqUcogHWt5gyGvTgEhwBwBP1kYrVnBlhB2nuWHLYpJDI6b
18uBoqKrHtrcdgXsKumSP0OKpn0nbYxknOvNYVjUUR6plMboUBaWX1oKoR6pNzTEHS
19al4bIU7XMwppkR3KNQIDAQAB
20-----END PUBLIC KEY-----`;
21
22 function getSpkiDer(spkiPem) {
23 const pemHeader = "-----BEGIN PUBLIC KEY-----";
24 const pemFooter = "-----END PUBLIC KEY-----";
25 var pemContents = spkiPem.substring(
26 pemHeader.length,
27 spkiPem.length - pemFooter.length
28 );
29 var binaryDerString = window.atob(pemContents);
30 return str2ab(binaryDerString);
31 }
32
33 async function importPublicKey(spkiPem) {
34 return await window.crypto.subtle.importKey(
35 "spki",
36 getSpkiDer(spkiPem),
37 {
38 name: "RSA-OAEP",
39 hash: "SHA-256",
40 },
41 true,
42 ["encrypt"]
43 );
44 }
45
46 async function encryptRSA(key, plaintext) {
47 let encrypted = await window.crypto.subtle.encrypt(
48 {
49 name: "RSA-OAEP",
50 },
51 key,
52 plaintext
53 );
54 return encrypted;
55 }
56
57 function str2ab(str) {
58 const buf = new ArrayBuffer(str.length);
59 const bufView = new Uint8Array(buf);
60 for (let i = 0, strLen = str.length; i < strLen; i++) {
61 bufView[i] = str.charCodeAt(i);
62 }
63 return buf;
64 }
65
66 function ab2str(buf) {
67 return String.fromCharCode.apply(null, new Uint8Array(buf));
68 }
69
70 async function encrypt(plaintext) {
71 const pub = await importPublicKey(publicKey);
72 const encrypted = await encryptRSA(
73 pub,
74 new TextEncoder().encode(plaintext)
75 );
76 const encryptedBase64 = window.btoa(ab2str(encrypted));
77 console.log(encryptedBase64);
78 }
79
80 encrypt("I want to decrypt this string in C#");
81
82 })();private static void Decrypt()
83{
84 var name = "test";
85 var encryptedBase64 = @"Rzabx5380rkx2+KKB+HaJP2dOXDcOC7SkYOy4HN8+Nb9HmjqeZfGQlf+ZUa6uAfAJ3oAB2iIlHlnx+iXK3XDIX3izjoW1eeiNmdOWieNCu6YXqW4denUVEv0Z4EpAmEYgVImnEzoMdmPDEcl9UHgdWUmS4Bnq6T8Yqh3UZ/4NOc=";
86 var encrypted = Convert.FromBase64String(encryptedBase64);
87 using var privateKey = new RSACryptoServiceProvider();
88 privateKey.FromXmlString(File.ReadAllText(name + "_priv.xml"));
89 var decryptedBytes = privateKey.Decrypt(encrypted, false);
90 var dectryptedText = Encoding.UTF8.GetString(decryptedBytes);
91}
92Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Wrong parameter
93 CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
94 RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
95System.Security.Cryptography.CryptographicException: Cryptography_OAEPDecoding,
96 CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
97 RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
98-----BEGIN PRIVATE KEY-----
99MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMbLxu2tudI0/Pu9
100Yp9BcrEpfODbxkPyMIB3uAZh9QgWoqpRyiAda3mDIa9OASHAHAE/WRitWcGWEHae
1015YctikkMjpu4Gioqse2tx2Bewq6ZI/Q4qmfSdtjGSc681hWNRRHqmUxuhQFpZfWg
102qhHqk3NMQdJqXhshTtczCmmRHco1AgMBAAECgYEAokAVN02wOQm4ZPp4cMSpCEF1
103Q8z8L96OiXusvcDbjWN0FhC1KKr6We2V44+FyvcRpE8At+xcMmz5OOeNLFwV3QLZ
104GOYjZXP5dmRC3mG7HOv0Iu4QqAQCMEzLf998+6RwA24U74ysm+6CVCeVWZLtJSi/
105UdQm3jho086iQF9UOo0CQQDjjhZl/fOqqb9nvW3rvSNwsdzSYoGpfx22uzrJplN2
106wpFO6XCorAGMO6lHI3Ua8A0OSNO1ybkhG2iZOkPoEGWHAkEA36VhsUFNQr4RO7gL
107oWpB+D2QtciZjnHm+QGRlfDl1mq527LHnHURrBQVRcHR3OgQbJ1wsSi4IjcKJ3l6
108EtcBYwJBAKRTtIsc1D0XbljdLCcEJDa6yuvHJTmgyXVvSenbSgTGRycEX03/QPLj
109FsB/s46rcdIx92kc7qsg3u1gbS+Fv7sCQQC5QHaxqxPiayo/O2524FuQ0v5hda6s
110rXDTZhdACnF3sKQPdgGeeeKPlXshczDxOVERh0BnnwEXZlwE4rzZijtdAkEA2gXb
111e/4gNIAuowBdgs1nXtuLKTP/HJzPIfil6zcF82Jc5dy7lR7nJCl088w0t1a0ebx5
112LrC2qjX4SMEUbMTkNg==
113-----END PRIVATE KEY-----`
114
1private static void GeneratePrivatePublicKeyPair() {
2 var name = "test";
3 var privateKeyXmlFile = name + "_priv.xml";
4 var publicKeyXmlFile = name + "_pub.xml";
5 var publicKeyFile = name + ".pub";
6
7 using var provider = new RSACryptoServiceProvider(1024);
8 File.WriteAllText(privateKeyXmlFile, provider.ToXmlString(true));
9 File.WriteAllText(publicKeyXmlFile, provider.ToXmlString(false));
10 using var publicKeyWriter = File.CreateText(publicKeyFile);
11 ExportPublicKey(provider, publicKeyWriter);
12}
13(() => {
14
15 const publicKey = `-----BEGIN PUBLIC KEY-----
16MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGy8btrbnSNPz7vWKfQXKxKXzg
1728ZD8jCAd7gGYfUIFqKqUcogHWt5gyGvTgEhwBwBP1kYrVnBlhB2nuWHLYpJDI6b
18uBoqKrHtrcdgXsKumSP0OKpn0nbYxknOvNYVjUUR6plMboUBaWX1oKoR6pNzTEHS
19al4bIU7XMwppkR3KNQIDAQAB
20-----END PUBLIC KEY-----`;
21
22 function getSpkiDer(spkiPem) {
23 const pemHeader = "-----BEGIN PUBLIC KEY-----";
24 const pemFooter = "-----END PUBLIC KEY-----";
25 var pemContents = spkiPem.substring(
26 pemHeader.length,
27 spkiPem.length - pemFooter.length
28 );
29 var binaryDerString = window.atob(pemContents);
30 return str2ab(binaryDerString);
31 }
32
33 async function importPublicKey(spkiPem) {
34 return await window.crypto.subtle.importKey(
35 "spki",
36 getSpkiDer(spkiPem),
37 {
38 name: "RSA-OAEP",
39 hash: "SHA-256",
40 },
41 true,
42 ["encrypt"]
43 );
44 }
45
46 async function encryptRSA(key, plaintext) {
47 let encrypted = await window.crypto.subtle.encrypt(
48 {
49 name: "RSA-OAEP",
50 },
51 key,
52 plaintext
53 );
54 return encrypted;
55 }
56
57 function str2ab(str) {
58 const buf = new ArrayBuffer(str.length);
59 const bufView = new Uint8Array(buf);
60 for (let i = 0, strLen = str.length; i < strLen; i++) {
61 bufView[i] = str.charCodeAt(i);
62 }
63 return buf;
64 }
65
66 function ab2str(buf) {
67 return String.fromCharCode.apply(null, new Uint8Array(buf));
68 }
69
70 async function encrypt(plaintext) {
71 const pub = await importPublicKey(publicKey);
72 const encrypted = await encryptRSA(
73 pub,
74 new TextEncoder().encode(plaintext)
75 );
76 const encryptedBase64 = window.btoa(ab2str(encrypted));
77 console.log(encryptedBase64);
78 }
79
80 encrypt("I want to decrypt this string in C#");
81
82 })();private static void Decrypt()
83{
84 var name = "test";
85 var encryptedBase64 = @"Rzabx5380rkx2+KKB+HaJP2dOXDcOC7SkYOy4HN8+Nb9HmjqeZfGQlf+ZUa6uAfAJ3oAB2iIlHlnx+iXK3XDIX3izjoW1eeiNmdOWieNCu6YXqW4denUVEv0Z4EpAmEYgVImnEzoMdmPDEcl9UHgdWUmS4Bnq6T8Yqh3UZ/4NOc=";
86 var encrypted = Convert.FromBase64String(encryptedBase64);
87 using var privateKey = new RSACryptoServiceProvider();
88 privateKey.FromXmlString(File.ReadAllText(name + "_priv.xml"));
89 var decryptedBytes = privateKey.Decrypt(encrypted, false);
90 var dectryptedText = Encoding.UTF8.GetString(decryptedBytes);
91}
92Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Wrong parameter
93 CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
94 RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
95System.Security.Cryptography.CryptographicException: Cryptography_OAEPDecoding,
96 CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
97 RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
98-----BEGIN PRIVATE KEY-----
99MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMbLxu2tudI0/Pu9
100Yp9BcrEpfODbxkPyMIB3uAZh9QgWoqpRyiAda3mDIa9OASHAHAE/WRitWcGWEHae
1015YctikkMjpu4Gioqse2tx2Bewq6ZI/Q4qmfSdtjGSc681hWNRRHqmUxuhQFpZfWg
102qhHqk3NMQdJqXhshTtczCmmRHco1AgMBAAECgYEAokAVN02wOQm4ZPp4cMSpCEF1
103Q8z8L96OiXusvcDbjWN0FhC1KKr6We2V44+FyvcRpE8At+xcMmz5OOeNLFwV3QLZ
104GOYjZXP5dmRC3mG7HOv0Iu4QqAQCMEzLf998+6RwA24U74ysm+6CVCeVWZLtJSi/
105UdQm3jho086iQF9UOo0CQQDjjhZl/fOqqb9nvW3rvSNwsdzSYoGpfx22uzrJplN2
106wpFO6XCorAGMO6lHI3Ua8A0OSNO1ybkhG2iZOkPoEGWHAkEA36VhsUFNQr4RO7gL
107oWpB+D2QtciZjnHm+QGRlfDl1mq527LHnHURrBQVRcHR3OgQbJ1wsSi4IjcKJ3l6
108EtcBYwJBAKRTtIsc1D0XbljdLCcEJDa6yuvHJTmgyXVvSenbSgTGRycEX03/QPLj
109FsB/s46rcdIx92kc7qsg3u1gbS+Fv7sCQQC5QHaxqxPiayo/O2524FuQ0v5hda6s
110rXDTZhdACnF3sKQPdgGeeeKPlXshczDxOVERh0BnnwEXZlwE4rzZijtdAkEA2gXb
111e/4gNIAuowBdgs1nXtuLKTP/HJzPIfil6zcF82Jc5dy7lR7nJCl088w0t1a0ebx5
112LrC2qjX4SMEUbMTkNg==
113-----END PRIVATE KEY-----`
114-----BEGIN PUBLIC KEY-----
115MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGy8btrbnSNPz7vWKfQXKxKXzg
11628ZD8jCAd7gGYfUIFqKqUcogHWt5gyGvTgEhwBwBP1kYrVnBlhB2nuWHLYpJDI6b
117uBoqKrHtrcdgXsKumSP0OKpn0nbYxknOvNYVjUUR6plMboUBaWX1oKoR6pNzTEHS
118al4bIU7XMwppkR3KNQIDAQAB
119-----END PUBLIC KEY-----
120
1private static void GeneratePrivatePublicKeyPair() {
2 var name = "test";
3 var privateKeyXmlFile = name + "_priv.xml";
4 var publicKeyXmlFile = name + "_pub.xml";
5 var publicKeyFile = name + ".pub";
6
7 using var provider = new RSACryptoServiceProvider(1024);
8 File.WriteAllText(privateKeyXmlFile, provider.ToXmlString(true));
9 File.WriteAllText(publicKeyXmlFile, provider.ToXmlString(false));
10 using var publicKeyWriter = File.CreateText(publicKeyFile);
11 ExportPublicKey(provider, publicKeyWriter);
12}
13(() => {
14
15 const publicKey = `-----BEGIN PUBLIC KEY-----
16MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGy8btrbnSNPz7vWKfQXKxKXzg
1728ZD8jCAd7gGYfUIFqKqUcogHWt5gyGvTgEhwBwBP1kYrVnBlhB2nuWHLYpJDI6b
18uBoqKrHtrcdgXsKumSP0OKpn0nbYxknOvNYVjUUR6plMboUBaWX1oKoR6pNzTEHS
19al4bIU7XMwppkR3KNQIDAQAB
20-----END PUBLIC KEY-----`;
21
22 function getSpkiDer(spkiPem) {
23 const pemHeader = "-----BEGIN PUBLIC KEY-----";
24 const pemFooter = "-----END PUBLIC KEY-----";
25 var pemContents = spkiPem.substring(
26 pemHeader.length,
27 spkiPem.length - pemFooter.length
28 );
29 var binaryDerString = window.atob(pemContents);
30 return str2ab(binaryDerString);
31 }
32
33 async function importPublicKey(spkiPem) {
34 return await window.crypto.subtle.importKey(
35 "spki",
36 getSpkiDer(spkiPem),
37 {
38 name: "RSA-OAEP",
39 hash: "SHA-256",
40 },
41 true,
42 ["encrypt"]
43 );
44 }
45
46 async function encryptRSA(key, plaintext) {
47 let encrypted = await window.crypto.subtle.encrypt(
48 {
49 name: "RSA-OAEP",
50 },
51 key,
52 plaintext
53 );
54 return encrypted;
55 }
56
57 function str2ab(str) {
58 const buf = new ArrayBuffer(str.length);
59 const bufView = new Uint8Array(buf);
60 for (let i = 0, strLen = str.length; i < strLen; i++) {
61 bufView[i] = str.charCodeAt(i);
62 }
63 return buf;
64 }
65
66 function ab2str(buf) {
67 return String.fromCharCode.apply(null, new Uint8Array(buf));
68 }
69
70 async function encrypt(plaintext) {
71 const pub = await importPublicKey(publicKey);
72 const encrypted = await encryptRSA(
73 pub,
74 new TextEncoder().encode(plaintext)
75 );
76 const encryptedBase64 = window.btoa(ab2str(encrypted));
77 console.log(encryptedBase64);
78 }
79
80 encrypt("I want to decrypt this string in C#");
81
82 })();private static void Decrypt()
83{
84 var name = "test";
85 var encryptedBase64 = @"Rzabx5380rkx2+KKB+HaJP2dOXDcOC7SkYOy4HN8+Nb9HmjqeZfGQlf+ZUa6uAfAJ3oAB2iIlHlnx+iXK3XDIX3izjoW1eeiNmdOWieNCu6YXqW4denUVEv0Z4EpAmEYgVImnEzoMdmPDEcl9UHgdWUmS4Bnq6T8Yqh3UZ/4NOc=";
86 var encrypted = Convert.FromBase64String(encryptedBase64);
87 using var privateKey = new RSACryptoServiceProvider();
88 privateKey.FromXmlString(File.ReadAllText(name + "_priv.xml"));
89 var decryptedBytes = privateKey.Decrypt(encrypted, false);
90 var dectryptedText = Encoding.UTF8.GetString(decryptedBytes);
91}
92Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Wrong parameter
93 CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
94 RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
95System.Security.Cryptography.CryptographicException: Cryptography_OAEPDecoding,
96 CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
97 RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
98-----BEGIN PRIVATE KEY-----
99MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMbLxu2tudI0/Pu9
100Yp9BcrEpfODbxkPyMIB3uAZh9QgWoqpRyiAda3mDIa9OASHAHAE/WRitWcGWEHae
1015YctikkMjpu4Gioqse2tx2Bewq6ZI/Q4qmfSdtjGSc681hWNRRHqmUxuhQFpZfWg
102qhHqk3NMQdJqXhshTtczCmmRHco1AgMBAAECgYEAokAVN02wOQm4ZPp4cMSpCEF1
103Q8z8L96OiXusvcDbjWN0FhC1KKr6We2V44+FyvcRpE8At+xcMmz5OOeNLFwV3QLZ
104GOYjZXP5dmRC3mG7HOv0Iu4QqAQCMEzLf998+6RwA24U74ysm+6CVCeVWZLtJSi/
105UdQm3jho086iQF9UOo0CQQDjjhZl/fOqqb9nvW3rvSNwsdzSYoGpfx22uzrJplN2
106wpFO6XCorAGMO6lHI3Ua8A0OSNO1ybkhG2iZOkPoEGWHAkEA36VhsUFNQr4RO7gL
107oWpB+D2QtciZjnHm+QGRlfDl1mq527LHnHURrBQVRcHR3OgQbJ1wsSi4IjcKJ3l6
108EtcBYwJBAKRTtIsc1D0XbljdLCcEJDa6yuvHJTmgyXVvSenbSgTGRycEX03/QPLj
109FsB/s46rcdIx92kc7qsg3u1gbS+Fv7sCQQC5QHaxqxPiayo/O2524FuQ0v5hda6s
110rXDTZhdACnF3sKQPdgGeeeKPlXshczDxOVERh0BnnwEXZlwE4rzZijtdAkEA2gXb
111e/4gNIAuowBdgs1nXtuLKTP/HJzPIfil6zcF82Jc5dy7lR7nJCl088w0t1a0ebx5
112LrC2qjX4SMEUbMTkNg==
113-----END PRIVATE KEY-----`
114-----BEGIN PUBLIC KEY-----
115MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGy8btrbnSNPz7vWKfQXKxKXzg
11628ZD8jCAd7gGYfUIFqKqUcogHWt5gyGvTgEhwBwBP1kYrVnBlhB2nuWHLYpJDI6b
117uBoqKrHtrcdgXsKumSP0OKpn0nbYxknOvNYVjUUR6plMboUBaWX1oKoR6pNzTEHS
118al4bIU7XMwppkR3KNQIDAQAB
119-----END PUBLIC KEY-----
120<RSAKeyValue><Modulus>xsvG7a250jT8+71in0FysSl84NvGQ/IwgHe4BmH1CBaiqlHKIB1reYMhr04BIcAcAT9ZGK1ZwZYQdp7lhy2KSQyOm7gaKiqx7a3HYF7Crpkj9DiqZ9J22MZJzrzWFY1FEeqZTG6FAWll9aCqEeqTc0xB0mpeGyFO1zMKaZEdyjU=</Modulus><Exponent>AQAB</Exponent><P>444WZf3zqqm/Z71t670jcLHc0mKBqX8dtrs6yaZTdsKRTulwqKwBjDupRyN1GvANDkjTtcm5IRtomTpD6BBlhw==</P><Q>36VhsUFNQr4RO7gLoWpB+D2QtciZjnHm+QGRlfDl1mq527LHnHURrBQVRcHR3OgQbJ1wsSi4IjcKJ3l6EtcBYw==</Q><DP>pFO0ixzUPRduWN0sJwQkNrrK68clOaDJdW9J6dtKBMZHJwRfTf9A8uMWwH+zjqtx0jH3aRzuqyDe7WBtL4W/uw==</DP><DQ>uUB2sasT4msqPztuduBbkNL+YXWurK1w02YXQApxd7CkD3YBnnnij5V7IXMw8TlREYdAZ58BF2ZcBOK82Yo7XQ==</DQ><InverseQ>2gXbe/4gNIAuowBdgs1nXtuLKTP/HJzPIfil6zcF82Jc5dy7lR7nJCl088w0t1a0ebx5LrC2qjX4SMEUbMTkNg==</InverseQ><D>okAVN02wOQm4ZPp4cMSpCEF1Q8z8L96OiXusvcDbjWN0FhC1KKr6We2V44+FyvcRpE8At+xcMmz5OOeNLFwV3QLZGOYjZXP5dmRC3mG7HOv0Iu4QqAQCMEzLf998+6RwA24U74ysm+6CVCeVWZLtJSi/UdQm3jho086iQF9UOo0=</D></RSAKeyValue>
121
1private static void GeneratePrivatePublicKeyPair() {
2 var name = "test";
3 var privateKeyXmlFile = name + "_priv.xml";
4 var publicKeyXmlFile = name + "_pub.xml";
5 var publicKeyFile = name + ".pub";
6
7 using var provider = new RSACryptoServiceProvider(1024);
8 File.WriteAllText(privateKeyXmlFile, provider.ToXmlString(true));
9 File.WriteAllText(publicKeyXmlFile, provider.ToXmlString(false));
10 using var publicKeyWriter = File.CreateText(publicKeyFile);
11 ExportPublicKey(provider, publicKeyWriter);
12}
13(() => {
14
15 const publicKey = `-----BEGIN PUBLIC KEY-----
16MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGy8btrbnSNPz7vWKfQXKxKXzg
1728ZD8jCAd7gGYfUIFqKqUcogHWt5gyGvTgEhwBwBP1kYrVnBlhB2nuWHLYpJDI6b
18uBoqKrHtrcdgXsKumSP0OKpn0nbYxknOvNYVjUUR6plMboUBaWX1oKoR6pNzTEHS
19al4bIU7XMwppkR3KNQIDAQAB
20-----END PUBLIC KEY-----`;
21
22 function getSpkiDer(spkiPem) {
23 const pemHeader = "-----BEGIN PUBLIC KEY-----";
24 const pemFooter = "-----END PUBLIC KEY-----";
25 var pemContents = spkiPem.substring(
26 pemHeader.length,
27 spkiPem.length - pemFooter.length
28 );
29 var binaryDerString = window.atob(pemContents);
30 return str2ab(binaryDerString);
31 }
32
33 async function importPublicKey(spkiPem) {
34 return await window.crypto.subtle.importKey(
35 "spki",
36 getSpkiDer(spkiPem),
37 {
38 name: "RSA-OAEP",
39 hash: "SHA-256",
40 },
41 true,
42 ["encrypt"]
43 );
44 }
45
46 async function encryptRSA(key, plaintext) {
47 let encrypted = await window.crypto.subtle.encrypt(
48 {
49 name: "RSA-OAEP",
50 },
51 key,
52 plaintext
53 );
54 return encrypted;
55 }
56
57 function str2ab(str) {
58 const buf = new ArrayBuffer(str.length);
59 const bufView = new Uint8Array(buf);
60 for (let i = 0, strLen = str.length; i < strLen; i++) {
61 bufView[i] = str.charCodeAt(i);
62 }
63 return buf;
64 }
65
66 function ab2str(buf) {
67 return String.fromCharCode.apply(null, new Uint8Array(buf));
68 }
69
70 async function encrypt(plaintext) {
71 const pub = await importPublicKey(publicKey);
72 const encrypted = await encryptRSA(
73 pub,
74 new TextEncoder().encode(plaintext)
75 );
76 const encryptedBase64 = window.btoa(ab2str(encrypted));
77 console.log(encryptedBase64);
78 }
79
80 encrypt("I want to decrypt this string in C#");
81
82 })();private static void Decrypt()
83{
84 var name = "test";
85 var encryptedBase64 = @"Rzabx5380rkx2+KKB+HaJP2dOXDcOC7SkYOy4HN8+Nb9HmjqeZfGQlf+ZUa6uAfAJ3oAB2iIlHlnx+iXK3XDIX3izjoW1eeiNmdOWieNCu6YXqW4denUVEv0Z4EpAmEYgVImnEzoMdmPDEcl9UHgdWUmS4Bnq6T8Yqh3UZ/4NOc=";
86 var encrypted = Convert.FromBase64String(encryptedBase64);
87 using var privateKey = new RSACryptoServiceProvider();
88 privateKey.FromXmlString(File.ReadAllText(name + "_priv.xml"));
89 var decryptedBytes = privateKey.Decrypt(encrypted, false);
90 var dectryptedText = Encoding.UTF8.GetString(decryptedBytes);
91}
92Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Wrong parameter
93 CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
94 RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
95System.Security.Cryptography.CryptographicException: Cryptography_OAEPDecoding,
96 CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
97 RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
98-----BEGIN PRIVATE KEY-----
99MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMbLxu2tudI0/Pu9
100Yp9BcrEpfODbxkPyMIB3uAZh9QgWoqpRyiAda3mDIa9OASHAHAE/WRitWcGWEHae
1015YctikkMjpu4Gioqse2tx2Bewq6ZI/Q4qmfSdtjGSc681hWNRRHqmUxuhQFpZfWg
102qhHqk3NMQdJqXhshTtczCmmRHco1AgMBAAECgYEAokAVN02wOQm4ZPp4cMSpCEF1
103Q8z8L96OiXusvcDbjWN0FhC1KKr6We2V44+FyvcRpE8At+xcMmz5OOeNLFwV3QLZ
104GOYjZXP5dmRC3mG7HOv0Iu4QqAQCMEzLf998+6RwA24U74ysm+6CVCeVWZLtJSi/
105UdQm3jho086iQF9UOo0CQQDjjhZl/fOqqb9nvW3rvSNwsdzSYoGpfx22uzrJplN2
106wpFO6XCorAGMO6lHI3Ua8A0OSNO1ybkhG2iZOkPoEGWHAkEA36VhsUFNQr4RO7gL
107oWpB+D2QtciZjnHm+QGRlfDl1mq527LHnHURrBQVRcHR3OgQbJ1wsSi4IjcKJ3l6
108EtcBYwJBAKRTtIsc1D0XbljdLCcEJDa6yuvHJTmgyXVvSenbSgTGRycEX03/QPLj
109FsB/s46rcdIx92kc7qsg3u1gbS+Fv7sCQQC5QHaxqxPiayo/O2524FuQ0v5hda6s
110rXDTZhdACnF3sKQPdgGeeeKPlXshczDxOVERh0BnnwEXZlwE4rzZijtdAkEA2gXb
111e/4gNIAuowBdgs1nXtuLKTP/HJzPIfil6zcF82Jc5dy7lR7nJCl088w0t1a0ebx5
112LrC2qjX4SMEUbMTkNg==
113-----END PRIVATE KEY-----`
114-----BEGIN PUBLIC KEY-----
115MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGy8btrbnSNPz7vWKfQXKxKXzg
11628ZD8jCAd7gGYfUIFqKqUcogHWt5gyGvTgEhwBwBP1kYrVnBlhB2nuWHLYpJDI6b
117uBoqKrHtrcdgXsKumSP0OKpn0nbYxknOvNYVjUUR6plMboUBaWX1oKoR6pNzTEHS
118al4bIU7XMwppkR3KNQIDAQAB
119-----END PUBLIC KEY-----
120<RSAKeyValue><Modulus>xsvG7a250jT8+71in0FysSl84NvGQ/IwgHe4BmH1CBaiqlHKIB1reYMhr04BIcAcAT9ZGK1ZwZYQdp7lhy2KSQyOm7gaKiqx7a3HYF7Crpkj9DiqZ9J22MZJzrzWFY1FEeqZTG6FAWll9aCqEeqTc0xB0mpeGyFO1zMKaZEdyjU=</Modulus><Exponent>AQAB</Exponent><P>444WZf3zqqm/Z71t670jcLHc0mKBqX8dtrs6yaZTdsKRTulwqKwBjDupRyN1GvANDkjTtcm5IRtomTpD6BBlhw==</P><Q>36VhsUFNQr4RO7gLoWpB+D2QtciZjnHm+QGRlfDl1mq527LHnHURrBQVRcHR3OgQbJ1wsSi4IjcKJ3l6EtcBYw==</Q><DP>pFO0ixzUPRduWN0sJwQkNrrK68clOaDJdW9J6dtKBMZHJwRfTf9A8uMWwH+zjqtx0jH3aRzuqyDe7WBtL4W/uw==</DP><DQ>uUB2sasT4msqPztuduBbkNL+YXWurK1w02YXQApxd7CkD3YBnnnij5V7IXMw8TlREYdAZ58BF2ZcBOK82Yo7XQ==</DQ><InverseQ>2gXbe/4gNIAuowBdgs1nXtuLKTP/HJzPIfil6zcF82Jc5dy7lR7nJCl088w0t1a0ebx5LrC2qjX4SMEUbMTkNg==</InverseQ><D>okAVN02wOQm4ZPp4cMSpCEF1Q8z8L96OiXusvcDbjWN0FhC1KKr6We2V44+FyvcRpE8At+xcMmz5OOeNLFwV3QLZGOYjZXP5dmRC3mG7HOv0Iu4QqAQCMEzLf998+6RwA24U74ysm+6CVCeVWZLtJSi/UdQm3jho086iQF9UOo0=</D></RSAKeyValue>
121<RSAKeyValue><Modulus>xsvG7a250jT8+71in0FysSl84NvGQ/IwgHe4BmH1CBaiqlHKIB1reYMhr04BIcAcAT9ZGK1ZwZYQdp7lhy2KSQyOm7gaKiqx7a3HYF7Crpkj9DiqZ9J22MZJzrzWFY1FEeqZTG6FAWll9aCqEeqTc0xB0mpeGyFO1zMKaZEdyjU=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
122
Just to make it clear what I want to achive. I am aware that using a private in a browser might be a bad idea. But in my case this is required:
App 1Internal webapp that needs to write encrypted data to an NDEF Tag using Web NFC API and is the one that needs the private key.
App 2Webapp that reads the encrypted data from the NEDF tag and transfers it to a .NET Webapp (App 3)
App 3Reads the encrypted data from App 2 and decrypts it.
ANSWER
Answered 2022-Jan-24 at 15:42You need to encrypt with the private key and then decrypt with the public key
QUESTION
Export Certificate as PFX with proper chain of signing
Asked 2022-Jan-10 at 17:12I read some posts (that don't exist anymore) and came up with the following code that generates a PFX certificate. It works fine to the part of creating this self-signed certificate.
I'm trying to expand this to crate a self-signed certificate and from that one, create it's "childs". I tryed many things but none of then actually export the certificate with it's chain as result.
The current code get's to a point of exporting a PFX with a containing CA and importing it would include both certificates, but not associate then with each other.
It's kind of a long code, but the action should work on the last "Create" funcion of it.
1using Sys = global::System;
2using SysInterop = global::System.Runtime.InteropServices;
3using SysCry509 = global::System.Security.Cryptography.X509Certificates;
4using MdPFX = global::PFX;
5public static class PFX
6{
7 #region NativeCode
8 private const string DLL_Kernel = "kernel32.dll";
9 private const string DLL_AdvApi = "AdvApi32.dll";
10 private const string DLL_Crypt = "Crypt32.dll";
11
12 [SysInterop.StructLayout(SysInterop.LayoutKind.Sequential)] private struct SystemTime
13 {
14 public short Year;
15 public short Month;
16 public short DayOfWeek;
17 public short Day;
18 public short Hour;
19 public short Minute;
20 public short Second;
21 public short Milliseconds;
22 }
23
24 [SysInterop.StructLayout(SysInterop.LayoutKind.Sequential)] private struct CryptoApiBlob
25 {
26 public int DataLength;
27 public Sys.IntPtr Data;
28
29 public CryptoApiBlob(int dataLength, Sys.IntPtr data)
30 {
31 this.DataLength = dataLength;
32 this.Data = data;
33 }
34 }
35
36 [SysInterop.StructLayout(SysInterop.LayoutKind.Sequential)] private struct CryptKeyProviderInformation
37 {
38 [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] public string ContainerName;
39 [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] public string ProviderName;
40 public int ProviderType;
41 public int Flags;
42 public int ProviderParameterCount;
43 public Sys.IntPtr ProviderParameters;
44 public int KeySpec;
45 }
46
47 [SysInterop.DllImport(MdPFX.DLL_Kernel, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool FileTimeToSystemTime([SysInterop.In] ref long fileTime, out MdPFX.SystemTime systemTime);
48 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptAcquireContextW(out Sys.IntPtr providerContext, [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] string container, [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] string provider, int providerType, int flags);
49 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptReleaseContext(Sys.IntPtr providerContext, int flags);
50 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptGenKey(Sys.IntPtr providerContext, int algorithmId, int flags, out Sys.IntPtr cryptKeyHandle);
51 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptDestroyKey(Sys.IntPtr cryptKeyHandle);
52 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertStrToNameW(int certificateEncodingType, Sys.IntPtr x500, int strType, Sys.IntPtr reserved, [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPArray)] [SysInterop.Out] byte[] encoded, ref int encodedLength, out Sys.IntPtr errorString);
53 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)] private static extern Sys.IntPtr CertCreateSelfSignCertificate(Sys.IntPtr providerHandle, [SysInterop.In] ref MdPFX.CryptoApiBlob subjectIssuerBlob, int flags, [SysInterop.In] ref MdPFX.CryptKeyProviderInformation keyProviderInformation, Sys.IntPtr signatureAlgorithm, [SysInterop.In] ref MdPFX.SystemTime startTime, [SysInterop.In] ref MdPFX.SystemTime endTime, Sys.IntPtr extensions);
54 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertFreeCertificateContext(Sys.IntPtr certificateContext);
55 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)] private static extern Sys.IntPtr CertOpenStore([SysInterop.MarshalAs(SysInterop.UnmanagedType.LPStr)] string storeProvider, int messageAndCertificateEncodingType, Sys.IntPtr cryptProvHandle, int flags, Sys.IntPtr parameters);
56 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertCloseStore(Sys.IntPtr certificateStoreHandle, int flags);
57 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertAddCertificateContextToStore(Sys.IntPtr certificateStoreHandle, Sys.IntPtr certificateContext, int addDisposition, out Sys.IntPtr storeContextPtr);
58 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertSetCertificateContextProperty(Sys.IntPtr certificateContext, int propertyId, int flags, [SysInterop.In] ref MdPFX.CryptKeyProviderInformation data);
59 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool PFXExportCertStoreEx(Sys.IntPtr certificateStoreHandle, ref MdPFX.CryptoApiBlob pfxBlob, Sys.IntPtr password, Sys.IntPtr reserved, int flags);
60 private static void Check(bool nativeCallSucceeded) { if (!nativeCallSucceeded) { SysInterop.Marshal.ThrowExceptionForHR(SysInterop.Marshal.GetHRForLastWin32Error()); } }
61
62 private static MdPFX.SystemTime ToSystemTime(Sys.DateTime dateTime)
63 {
64 long fileTime = dateTime.ToFileTime();
65 MdPFX.SystemTime systemTime = default(MdPFX.SystemTime);
66 MdPFX.Check(MdPFX.FileTimeToSystemTime(ref fileTime, out systemTime));
67 return systemTime;
68 }
69 #endregion
70
71 public static byte[] Create(string commonName, Sys.DateTime startTime, Sys.DateTime endTime, Sys.Security.SecureString password)
72 {
73 byte[] pfxData;
74 if (commonName == null) { commonName = string.Empty; }
75 MdPFX.SystemTime startSystemTime = MdPFX.ToSystemTime(startTime);
76 MdPFX.SystemTime endSystemTime = MdPFX.ToSystemTime(endTime);
77 string containerName = Sys.Guid.NewGuid().ToString();
78 SysInterop.GCHandle dataHandle = default(SysInterop.GCHandle);
79 Sys.IntPtr providerContext = Sys.IntPtr.Zero;
80 Sys.IntPtr cryptKey = Sys.IntPtr.Zero;
81 Sys.IntPtr certContext = Sys.IntPtr.Zero;
82 Sys.IntPtr certStore = Sys.IntPtr.Zero;
83 Sys.IntPtr storeCertContext = Sys.IntPtr.Zero;
84 Sys.IntPtr passwordPtr = Sys.IntPtr.Zero;
85 Sys.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
86 try
87 {
88 MdPFX.Check(MdPFX.CryptAcquireContextW(out providerContext, containerName, null, 1, 8));
89 MdPFX.Check(MdPFX.CryptGenKey(providerContext, 1, 1, out cryptKey));
90 Sys.IntPtr errorStringPtr = Sys.IntPtr.Zero;
91 int nameDataLength = 0;
92 byte[] nameData = null;
93 dataHandle = SysInterop.GCHandle.Alloc(commonName, SysInterop.GCHandleType.Pinned);
94 if (!MdPFX.CertStrToNameW(0x00010001, dataHandle.AddrOfPinnedObject(), 3, Sys.IntPtr.Zero, null, ref nameDataLength, out errorStringPtr)) { throw new Sys.ArgumentException(SysInterop.Marshal.PtrToStringUni(errorStringPtr)); }
95 nameData = new byte[nameDataLength];
96 if (!MdPFX.CertStrToNameW(0x00010001, dataHandle.AddrOfPinnedObject(), 3, Sys.IntPtr.Zero, nameData, ref nameDataLength, out errorStringPtr)) { throw new Sys.ArgumentException(SysInterop.Marshal.PtrToStringUni(errorStringPtr)); }
97 dataHandle.Free();
98 dataHandle = SysInterop.GCHandle.Alloc(nameData, SysInterop.GCHandleType.Pinned);
99 MdPFX.CryptoApiBlob nameBlob = new MdPFX.CryptoApiBlob(nameData.Length, dataHandle.AddrOfPinnedObject());
100 MdPFX.CryptKeyProviderInformation kpi = new MdPFX.CryptKeyProviderInformation();
101 kpi.ContainerName = containerName;
102 kpi.ProviderType = 1;
103 kpi.KeySpec = 1;
104 certContext = MdPFX.CertCreateSelfSignCertificate(providerContext, ref nameBlob, 0, ref kpi, Sys.IntPtr.Zero, ref startSystemTime, ref endSystemTime, Sys.IntPtr.Zero);
105 MdPFX.Check(certContext != Sys.IntPtr.Zero);
106 dataHandle.Free();
107 certStore = MdPFX.CertOpenStore("Memory", 0, Sys.IntPtr.Zero, 0x2000, Sys.IntPtr.Zero);
108 MdPFX.Check(certStore != Sys.IntPtr.Zero);
109 MdPFX.Check(MdPFX.CertAddCertificateContextToStore(certStore, certContext, 1, out storeCertContext));
110 MdPFX.CertSetCertificateContextProperty(storeCertContext, 2, 0, ref kpi);
111 if (password != null) { passwordPtr = SysInterop.Marshal.SecureStringToCoTaskMemUnicode(password); }
112 MdPFX.CryptoApiBlob pfxBlob = new MdPFX.CryptoApiBlob();
113 MdPFX.Check(MdPFX.PFXExportCertStoreEx(certStore, ref pfxBlob, passwordPtr, Sys.IntPtr.Zero, 7));
114 pfxData = new byte[pfxBlob.DataLength];
115 dataHandle = SysInterop.GCHandle.Alloc(pfxData, SysInterop.GCHandleType.Pinned);
116 pfxBlob.Data = dataHandle.AddrOfPinnedObject();
117 MdPFX.Check(MdPFX.PFXExportCertStoreEx(certStore, ref pfxBlob, passwordPtr, Sys.IntPtr.Zero, 7));
118 dataHandle.Free();
119 }
120 finally
121 {
122 if (passwordPtr != Sys.IntPtr.Zero) { SysInterop.Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr); }
123 if (dataHandle.IsAllocated) { dataHandle.Free(); }
124 if (certContext != Sys.IntPtr.Zero) { MdPFX.CertFreeCertificateContext(certContext); }
125 if (storeCertContext != Sys.IntPtr.Zero) { MdPFX.CertFreeCertificateContext(storeCertContext); }
126 if (certStore != Sys.IntPtr.Zero) { MdPFX.CertCloseStore(certStore, 0); }
127 if (cryptKey != Sys.IntPtr.Zero) { MdPFX.CryptDestroyKey(cryptKey); }
128 if (providerContext != Sys.IntPtr.Zero)
129 {
130 MdPFX.CryptReleaseContext(providerContext, 0);
131 MdPFX.CryptAcquireContextW(out providerContext, containerName, null, 1, 0x10);
132 }
133 }
134 return pfxData;
135 }
136
137 public static Sys.Security.SecureString CreateSecurePassword(string insecurePassword)
138 {
139 if (!string.IsNullOrEmpty(insecurePassword))
140 {
141 Sys.Security.SecureString password = new Sys.Security.SecureString();
142 foreach (char ch in insecurePassword) { password.AppendChar(ch); }
143 password.MakeReadOnly();
144 return password;
145 } else { return null; }
146 }
147
148 public static byte[] Create(string commonName, Sys.DateTime startTime, Sys.DateTime endTime, string insecurePassword)
149 {
150 byte[] pfxData;
151 Sys.Security.SecureString password = null;
152 try
153 {
154 password = MdPFX.CreateSecurePassword(insecurePassword);
155 pfxData = MdPFX.Create(commonName, startTime, endTime, password);
156 } finally { if (password != null) { password.Dispose(); } }
157 return pfxData;
158 }
159
160 public static byte[] Create(string commonName, int YearsValid, Sys.Security.SecureString password)
161 {
162 if (!commonName.StartsWith("CN=", Sys.StringComparison.OrdinalIgnoreCase)) { commonName = "CN=" + commonName; }
163 return MdPFX.Create(commonName, Sys.DateTime.Now, Sys.DateTime.Now.AddYears(YearsValid), password);
164 }
165
166 public static void Create(Sys.IO.Stream save, string commonName, int YearsValid, Sys.Security.SecureString password)
167 {
168 byte[] certificateData = MdPFX.Create(commonName, 5, password);
169 using (Sys.IO.BinaryWriter binWriter = new Sys.IO.BinaryWriter(save))
170 {
171 binWriter.Write(certificateData);
172 binWriter.Flush();
173 }
174 }
175
176 public static byte[] Create(string commonName, Sys.DateTime startTime, Sys.DateTime endTime) { return MdPFX.Create(commonName, startTime, endTime, (Sys.Security.SecureString)null); }
177 public static byte[] Create(string commonName, int YearsValid, string insecurePassword) { using (Sys.Security.SecureString password = MdPFX.CreateSecurePassword(insecurePassword)) { return MdPFX.Create(commonName, YearsValid, password); } }
178 public static void Create(Sys.IO.Stream save, string commonName, int YearsValid, string insecurePassword) { using (Sys.Security.SecureString password = MdPFX.CreateSecurePassword(insecurePassword)) { MdPFX.Create(save, commonName, YearsValid, password); } }
179 public static void Create(string savePath, string commonName, int YearsValid, Sys.Security.SecureString password) { using (Sys.IO.FileStream fStream = Sys.IO.File.Open(savePath, Sys.IO.FileMode.Create)) { MdPFX.Create(fStream, commonName, YearsValid, password); } }
180 public static void Create(string savePath, string commonName, int YearsValid, string insecurePassword) { using (Sys.Security.SecureString password = MdPFX.CreateSecurePassword(insecurePassword)) { using (Sys.IO.FileStream fStream = Sys.IO.File.Open(savePath, Sys.IO.FileMode.Create)) { MdPFX.Create(fStream, commonName, YearsValid, password); } } }
181
182 public static byte[] Create(SysCry509.X509Certificate2 certificate, string insecurePassword, SysCry509.X509Certificate2 signingCert, SysCry509.X509Certificate2Collection chain = null)
183 {
184 SysCry509.X509Certificate2Collection col = new SysCry509.X509Certificate2Collection(certificate);
185 if (chain != null) { col.AddRange(chain); }
186 if (signingCert != null)
187 {
188 SysCry509.X509Certificate2 sigCertNoPK = new SysCry509.X509Certificate2(signingCert.Export(SysCry509.X509ContentType.Cert));
189 col.Add(sigCertNoPK);
190 }
191 return col.Export(SysCry509.X509ContentType.Pfx, insecurePassword);
192 }
193
194 public static byte[] Create(string commonName, string insecurePassword, int YearsValid, SysCry509.X509Certificate2 signingCert, SysCry509.X509Certificate2Collection chain = null)
195 {
196 SysCry509.X509Certificate2 certificate = new SysCry509.X509Certificate2();
197 certificate.Import(MdPFX.Create(commonName, YearsValid, insecurePassword), insecurePassword, (SysCry509.X509KeyStorageFlags.PersistKeySet | SysCry509.X509KeyStorageFlags.Exportable));
198 return MdPFX.Create(certificate, insecurePassword, signingCert, chain: chain);
199 }
200
201 public static SysCry509.X509Certificate2 Load(byte[] rawData, string insecurePassword)
202 {
203 try
204 {
205 SysCry509.X509Certificate2 rCert = new SysCry509.X509Certificate2();
206 rCert.Import(rawData, insecurePassword, (SysCry509.X509KeyStorageFlags.PersistKeySet | SysCry509.X509KeyStorageFlags.Exportable));
207 return rCert;
208 } catch { return null; }
209 }
210
211 public static byte[] Create(string commonName, string insecurePassword, int YearsValid, bool Signed, SysCry509.X509Certificate2Collection chain = null)
212 {
213 if (Signed)
214 {
215 SysCry509.X509Store store = new SysCry509.X509Store(typeof(MdPFX).FullName, SysCry509.StoreLocation.LocalMachine);
216 store.Open(SysCry509.OpenFlags.ReadWrite);
217 const string rCertN = "A.Root.Cert.Name";
218 SysCry509.X509Certificate2 rCert = null;
219 if (store.Certificates.Count > 0) { foreach (SysCry509.X509Certificate2 c in store.Certificates) { if (c.SubjectName.Name == rCertN) { rCert = c; break; } } }
220 if (rCert == null)
221 {
222 rCert = MdPFX.Load(MdPFX.Create(rCertN, 10, "A.Root.Cert.Pass"), "A.Root.Cert.Pass");
223 store.Add(rCert);
224 }
225 store.Close();
226 return MdPFX.Create(commonName, insecurePassword, YearsValid, rCert, chain: chain);
227 } else { return MdPFX.Create(commonName, YearsValid, insecurePassword); }
228 }
229}
230
Then, if i run like this, it's not giving the certificate with chain to the "CA" created.
1using Sys = global::System;
2using SysInterop = global::System.Runtime.InteropServices;
3using SysCry509 = global::System.Security.Cryptography.X509Certificates;
4using MdPFX = global::PFX;
5public static class PFX
6{
7 #region NativeCode
8 private const string DLL_Kernel = "kernel32.dll";
9 private const string DLL_AdvApi = "AdvApi32.dll";
10 private const string DLL_Crypt = "Crypt32.dll";
11
12 [SysInterop.StructLayout(SysInterop.LayoutKind.Sequential)] private struct SystemTime
13 {
14 public short Year;
15 public short Month;
16 public short DayOfWeek;
17 public short Day;
18 public short Hour;
19 public short Minute;
20 public short Second;
21 public short Milliseconds;
22 }
23
24 [SysInterop.StructLayout(SysInterop.LayoutKind.Sequential)] private struct CryptoApiBlob
25 {
26 public int DataLength;
27 public Sys.IntPtr Data;
28
29 public CryptoApiBlob(int dataLength, Sys.IntPtr data)
30 {
31 this.DataLength = dataLength;
32 this.Data = data;
33 }
34 }
35
36 [SysInterop.StructLayout(SysInterop.LayoutKind.Sequential)] private struct CryptKeyProviderInformation
37 {
38 [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] public string ContainerName;
39 [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] public string ProviderName;
40 public int ProviderType;
41 public int Flags;
42 public int ProviderParameterCount;
43 public Sys.IntPtr ProviderParameters;
44 public int KeySpec;
45 }
46
47 [SysInterop.DllImport(MdPFX.DLL_Kernel, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool FileTimeToSystemTime([SysInterop.In] ref long fileTime, out MdPFX.SystemTime systemTime);
48 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptAcquireContextW(out Sys.IntPtr providerContext, [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] string container, [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] string provider, int providerType, int flags);
49 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptReleaseContext(Sys.IntPtr providerContext, int flags);
50 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptGenKey(Sys.IntPtr providerContext, int algorithmId, int flags, out Sys.IntPtr cryptKeyHandle);
51 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptDestroyKey(Sys.IntPtr cryptKeyHandle);
52 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertStrToNameW(int certificateEncodingType, Sys.IntPtr x500, int strType, Sys.IntPtr reserved, [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPArray)] [SysInterop.Out] byte[] encoded, ref int encodedLength, out Sys.IntPtr errorString);
53 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)] private static extern Sys.IntPtr CertCreateSelfSignCertificate(Sys.IntPtr providerHandle, [SysInterop.In] ref MdPFX.CryptoApiBlob subjectIssuerBlob, int flags, [SysInterop.In] ref MdPFX.CryptKeyProviderInformation keyProviderInformation, Sys.IntPtr signatureAlgorithm, [SysInterop.In] ref MdPFX.SystemTime startTime, [SysInterop.In] ref MdPFX.SystemTime endTime, Sys.IntPtr extensions);
54 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertFreeCertificateContext(Sys.IntPtr certificateContext);
55 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)] private static extern Sys.IntPtr CertOpenStore([SysInterop.MarshalAs(SysInterop.UnmanagedType.LPStr)] string storeProvider, int messageAndCertificateEncodingType, Sys.IntPtr cryptProvHandle, int flags, Sys.IntPtr parameters);
56 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertCloseStore(Sys.IntPtr certificateStoreHandle, int flags);
57 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertAddCertificateContextToStore(Sys.IntPtr certificateStoreHandle, Sys.IntPtr certificateContext, int addDisposition, out Sys.IntPtr storeContextPtr);
58 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertSetCertificateContextProperty(Sys.IntPtr certificateContext, int propertyId, int flags, [SysInterop.In] ref MdPFX.CryptKeyProviderInformation data);
59 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool PFXExportCertStoreEx(Sys.IntPtr certificateStoreHandle, ref MdPFX.CryptoApiBlob pfxBlob, Sys.IntPtr password, Sys.IntPtr reserved, int flags);
60 private static void Check(bool nativeCallSucceeded) { if (!nativeCallSucceeded) { SysInterop.Marshal.ThrowExceptionForHR(SysInterop.Marshal.GetHRForLastWin32Error()); } }
61
62 private static MdPFX.SystemTime ToSystemTime(Sys.DateTime dateTime)
63 {
64 long fileTime = dateTime.ToFileTime();
65 MdPFX.SystemTime systemTime = default(MdPFX.SystemTime);
66 MdPFX.Check(MdPFX.FileTimeToSystemTime(ref fileTime, out systemTime));
67 return systemTime;
68 }
69 #endregion
70
71 public static byte[] Create(string commonName, Sys.DateTime startTime, Sys.DateTime endTime, Sys.Security.SecureString password)
72 {
73 byte[] pfxData;
74 if (commonName == null) { commonName = string.Empty; }
75 MdPFX.SystemTime startSystemTime = MdPFX.ToSystemTime(startTime);
76 MdPFX.SystemTime endSystemTime = MdPFX.ToSystemTime(endTime);
77 string containerName = Sys.Guid.NewGuid().ToString();
78 SysInterop.GCHandle dataHandle = default(SysInterop.GCHandle);
79 Sys.IntPtr providerContext = Sys.IntPtr.Zero;
80 Sys.IntPtr cryptKey = Sys.IntPtr.Zero;
81 Sys.IntPtr certContext = Sys.IntPtr.Zero;
82 Sys.IntPtr certStore = Sys.IntPtr.Zero;
83 Sys.IntPtr storeCertContext = Sys.IntPtr.Zero;
84 Sys.IntPtr passwordPtr = Sys.IntPtr.Zero;
85 Sys.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
86 try
87 {
88 MdPFX.Check(MdPFX.CryptAcquireContextW(out providerContext, containerName, null, 1, 8));
89 MdPFX.Check(MdPFX.CryptGenKey(providerContext, 1, 1, out cryptKey));
90 Sys.IntPtr errorStringPtr = Sys.IntPtr.Zero;
91 int nameDataLength = 0;
92 byte[] nameData = null;
93 dataHandle = SysInterop.GCHandle.Alloc(commonName, SysInterop.GCHandleType.Pinned);
94 if (!MdPFX.CertStrToNameW(0x00010001, dataHandle.AddrOfPinnedObject(), 3, Sys.IntPtr.Zero, null, ref nameDataLength, out errorStringPtr)) { throw new Sys.ArgumentException(SysInterop.Marshal.PtrToStringUni(errorStringPtr)); }
95 nameData = new byte[nameDataLength];
96 if (!MdPFX.CertStrToNameW(0x00010001, dataHandle.AddrOfPinnedObject(), 3, Sys.IntPtr.Zero, nameData, ref nameDataLength, out errorStringPtr)) { throw new Sys.ArgumentException(SysInterop.Marshal.PtrToStringUni(errorStringPtr)); }
97 dataHandle.Free();
98 dataHandle = SysInterop.GCHandle.Alloc(nameData, SysInterop.GCHandleType.Pinned);
99 MdPFX.CryptoApiBlob nameBlob = new MdPFX.CryptoApiBlob(nameData.Length, dataHandle.AddrOfPinnedObject());
100 MdPFX.CryptKeyProviderInformation kpi = new MdPFX.CryptKeyProviderInformation();
101 kpi.ContainerName = containerName;
102 kpi.ProviderType = 1;
103 kpi.KeySpec = 1;
104 certContext = MdPFX.CertCreateSelfSignCertificate(providerContext, ref nameBlob, 0, ref kpi, Sys.IntPtr.Zero, ref startSystemTime, ref endSystemTime, Sys.IntPtr.Zero);
105 MdPFX.Check(certContext != Sys.IntPtr.Zero);
106 dataHandle.Free();
107 certStore = MdPFX.CertOpenStore("Memory", 0, Sys.IntPtr.Zero, 0x2000, Sys.IntPtr.Zero);
108 MdPFX.Check(certStore != Sys.IntPtr.Zero);
109 MdPFX.Check(MdPFX.CertAddCertificateContextToStore(certStore, certContext, 1, out storeCertContext));
110 MdPFX.CertSetCertificateContextProperty(storeCertContext, 2, 0, ref kpi);
111 if (password != null) { passwordPtr = SysInterop.Marshal.SecureStringToCoTaskMemUnicode(password); }
112 MdPFX.CryptoApiBlob pfxBlob = new MdPFX.CryptoApiBlob();
113 MdPFX.Check(MdPFX.PFXExportCertStoreEx(certStore, ref pfxBlob, passwordPtr, Sys.IntPtr.Zero, 7));
114 pfxData = new byte[pfxBlob.DataLength];
115 dataHandle = SysInterop.GCHandle.Alloc(pfxData, SysInterop.GCHandleType.Pinned);
116 pfxBlob.Data = dataHandle.AddrOfPinnedObject();
117 MdPFX.Check(MdPFX.PFXExportCertStoreEx(certStore, ref pfxBlob, passwordPtr, Sys.IntPtr.Zero, 7));
118 dataHandle.Free();
119 }
120 finally
121 {
122 if (passwordPtr != Sys.IntPtr.Zero) { SysInterop.Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr); }
123 if (dataHandle.IsAllocated) { dataHandle.Free(); }
124 if (certContext != Sys.IntPtr.Zero) { MdPFX.CertFreeCertificateContext(certContext); }
125 if (storeCertContext != Sys.IntPtr.Zero) { MdPFX.CertFreeCertificateContext(storeCertContext); }
126 if (certStore != Sys.IntPtr.Zero) { MdPFX.CertCloseStore(certStore, 0); }
127 if (cryptKey != Sys.IntPtr.Zero) { MdPFX.CryptDestroyKey(cryptKey); }
128 if (providerContext != Sys.IntPtr.Zero)
129 {
130 MdPFX.CryptReleaseContext(providerContext, 0);
131 MdPFX.CryptAcquireContextW(out providerContext, containerName, null, 1, 0x10);
132 }
133 }
134 return pfxData;
135 }
136
137 public static Sys.Security.SecureString CreateSecurePassword(string insecurePassword)
138 {
139 if (!string.IsNullOrEmpty(insecurePassword))
140 {
141 Sys.Security.SecureString password = new Sys.Security.SecureString();
142 foreach (char ch in insecurePassword) { password.AppendChar(ch); }
143 password.MakeReadOnly();
144 return password;
145 } else { return null; }
146 }
147
148 public static byte[] Create(string commonName, Sys.DateTime startTime, Sys.DateTime endTime, string insecurePassword)
149 {
150 byte[] pfxData;
151 Sys.Security.SecureString password = null;
152 try
153 {
154 password = MdPFX.CreateSecurePassword(insecurePassword);
155 pfxData = MdPFX.Create(commonName, startTime, endTime, password);
156 } finally { if (password != null) { password.Dispose(); } }
157 return pfxData;
158 }
159
160 public static byte[] Create(string commonName, int YearsValid, Sys.Security.SecureString password)
161 {
162 if (!commonName.StartsWith("CN=", Sys.StringComparison.OrdinalIgnoreCase)) { commonName = "CN=" + commonName; }
163 return MdPFX.Create(commonName, Sys.DateTime.Now, Sys.DateTime.Now.AddYears(YearsValid), password);
164 }
165
166 public static void Create(Sys.IO.Stream save, string commonName, int YearsValid, Sys.Security.SecureString password)
167 {
168 byte[] certificateData = MdPFX.Create(commonName, 5, password);
169 using (Sys.IO.BinaryWriter binWriter = new Sys.IO.BinaryWriter(save))
170 {
171 binWriter.Write(certificateData);
172 binWriter.Flush();
173 }
174 }
175
176 public static byte[] Create(string commonName, Sys.DateTime startTime, Sys.DateTime endTime) { return MdPFX.Create(commonName, startTime, endTime, (Sys.Security.SecureString)null); }
177 public static byte[] Create(string commonName, int YearsValid, string insecurePassword) { using (Sys.Security.SecureString password = MdPFX.CreateSecurePassword(insecurePassword)) { return MdPFX.Create(commonName, YearsValid, password); } }
178 public static void Create(Sys.IO.Stream save, string commonName, int YearsValid, string insecurePassword) { using (Sys.Security.SecureString password = MdPFX.CreateSecurePassword(insecurePassword)) { MdPFX.Create(save, commonName, YearsValid, password); } }
179 public static void Create(string savePath, string commonName, int YearsValid, Sys.Security.SecureString password) { using (Sys.IO.FileStream fStream = Sys.IO.File.Open(savePath, Sys.IO.FileMode.Create)) { MdPFX.Create(fStream, commonName, YearsValid, password); } }
180 public static void Create(string savePath, string commonName, int YearsValid, string insecurePassword) { using (Sys.Security.SecureString password = MdPFX.CreateSecurePassword(insecurePassword)) { using (Sys.IO.FileStream fStream = Sys.IO.File.Open(savePath, Sys.IO.FileMode.Create)) { MdPFX.Create(fStream, commonName, YearsValid, password); } } }
181
182 public static byte[] Create(SysCry509.X509Certificate2 certificate, string insecurePassword, SysCry509.X509Certificate2 signingCert, SysCry509.X509Certificate2Collection chain = null)
183 {
184 SysCry509.X509Certificate2Collection col = new SysCry509.X509Certificate2Collection(certificate);
185 if (chain != null) { col.AddRange(chain); }
186 if (signingCert != null)
187 {
188 SysCry509.X509Certificate2 sigCertNoPK = new SysCry509.X509Certificate2(signingCert.Export(SysCry509.X509ContentType.Cert));
189 col.Add(sigCertNoPK);
190 }
191 return col.Export(SysCry509.X509ContentType.Pfx, insecurePassword);
192 }
193
194 public static byte[] Create(string commonName, string insecurePassword, int YearsValid, SysCry509.X509Certificate2 signingCert, SysCry509.X509Certificate2Collection chain = null)
195 {
196 SysCry509.X509Certificate2 certificate = new SysCry509.X509Certificate2();
197 certificate.Import(MdPFX.Create(commonName, YearsValid, insecurePassword), insecurePassword, (SysCry509.X509KeyStorageFlags.PersistKeySet | SysCry509.X509KeyStorageFlags.Exportable));
198 return MdPFX.Create(certificate, insecurePassword, signingCert, chain: chain);
199 }
200
201 public static SysCry509.X509Certificate2 Load(byte[] rawData, string insecurePassword)
202 {
203 try
204 {
205 SysCry509.X509Certificate2 rCert = new SysCry509.X509Certificate2();
206 rCert.Import(rawData, insecurePassword, (SysCry509.X509KeyStorageFlags.PersistKeySet | SysCry509.X509KeyStorageFlags.Exportable));
207 return rCert;
208 } catch { return null; }
209 }
210
211 public static byte[] Create(string commonName, string insecurePassword, int YearsValid, bool Signed, SysCry509.X509Certificate2Collection chain = null)
212 {
213 if (Signed)
214 {
215 SysCry509.X509Store store = new SysCry509.X509Store(typeof(MdPFX).FullName, SysCry509.StoreLocation.LocalMachine);
216 store.Open(SysCry509.OpenFlags.ReadWrite);
217 const string rCertN = "A.Root.Cert.Name";
218 SysCry509.X509Certificate2 rCert = null;
219 if (store.Certificates.Count > 0) { foreach (SysCry509.X509Certificate2 c in store.Certificates) { if (c.SubjectName.Name == rCertN) { rCert = c; break; } } }
220 if (rCert == null)
221 {
222 rCert = MdPFX.Load(MdPFX.Create(rCertN, 10, "A.Root.Cert.Pass"), "A.Root.Cert.Pass");
223 store.Add(rCert);
224 }
225 store.Close();
226 return MdPFX.Create(commonName, insecurePassword, YearsValid, rCert, chain: chain);
227 } else { return MdPFX.Create(commonName, YearsValid, insecurePassword); }
228 }
229}
230internal static class Program
231{
232 internal static void Main()
233 {
234 Sys.IO.File.WriteAllBytes("C:\\Users\\User\\Desktop\\cert.pfx", MdPFX.Create("My.Name", "Pass.123", 10, true, chain: null));
235 }
236}
237
UPDATED QUESTION: 2022-01-10
So one thing, @bartonjs recomended me to check this link: https://stackoverflow.com/a/48210587/6535399 I beleave i've seen this before, but still went on it and copied the code (as is) on the soution to a new blank project and ran (adding the "Export" to PFX with password).
1using Sys = global::System;
2using SysInterop = global::System.Runtime.InteropServices;
3using SysCry509 = global::System.Security.Cryptography.X509Certificates;
4using MdPFX = global::PFX;
5public static class PFX
6{
7 #region NativeCode
8 private const string DLL_Kernel = "kernel32.dll";
9 private const string DLL_AdvApi = "AdvApi32.dll";
10 private const string DLL_Crypt = "Crypt32.dll";
11
12 [SysInterop.StructLayout(SysInterop.LayoutKind.Sequential)] private struct SystemTime
13 {
14 public short Year;
15 public short Month;
16 public short DayOfWeek;
17 public short Day;
18 public short Hour;
19 public short Minute;
20 public short Second;
21 public short Milliseconds;
22 }
23
24 [SysInterop.StructLayout(SysInterop.LayoutKind.Sequential)] private struct CryptoApiBlob
25 {
26 public int DataLength;
27 public Sys.IntPtr Data;
28
29 public CryptoApiBlob(int dataLength, Sys.IntPtr data)
30 {
31 this.DataLength = dataLength;
32 this.Data = data;
33 }
34 }
35
36 [SysInterop.StructLayout(SysInterop.LayoutKind.Sequential)] private struct CryptKeyProviderInformation
37 {
38 [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] public string ContainerName;
39 [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] public string ProviderName;
40 public int ProviderType;
41 public int Flags;
42 public int ProviderParameterCount;
43 public Sys.IntPtr ProviderParameters;
44 public int KeySpec;
45 }
46
47 [SysInterop.DllImport(MdPFX.DLL_Kernel, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool FileTimeToSystemTime([SysInterop.In] ref long fileTime, out MdPFX.SystemTime systemTime);
48 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptAcquireContextW(out Sys.IntPtr providerContext, [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] string container, [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPWStr)] string provider, int providerType, int flags);
49 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptReleaseContext(Sys.IntPtr providerContext, int flags);
50 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptGenKey(Sys.IntPtr providerContext, int algorithmId, int flags, out Sys.IntPtr cryptKeyHandle);
51 [SysInterop.DllImport(MdPFX.DLL_AdvApi, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CryptDestroyKey(Sys.IntPtr cryptKeyHandle);
52 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertStrToNameW(int certificateEncodingType, Sys.IntPtr x500, int strType, Sys.IntPtr reserved, [SysInterop.MarshalAs(SysInterop.UnmanagedType.LPArray)] [SysInterop.Out] byte[] encoded, ref int encodedLength, out Sys.IntPtr errorString);
53 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)] private static extern Sys.IntPtr CertCreateSelfSignCertificate(Sys.IntPtr providerHandle, [SysInterop.In] ref MdPFX.CryptoApiBlob subjectIssuerBlob, int flags, [SysInterop.In] ref MdPFX.CryptKeyProviderInformation keyProviderInformation, Sys.IntPtr signatureAlgorithm, [SysInterop.In] ref MdPFX.SystemTime startTime, [SysInterop.In] ref MdPFX.SystemTime endTime, Sys.IntPtr extensions);
54 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertFreeCertificateContext(Sys.IntPtr certificateContext);
55 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)] private static extern Sys.IntPtr CertOpenStore([SysInterop.MarshalAs(SysInterop.UnmanagedType.LPStr)] string storeProvider, int messageAndCertificateEncodingType, Sys.IntPtr cryptProvHandle, int flags, Sys.IntPtr parameters);
56 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertCloseStore(Sys.IntPtr certificateStoreHandle, int flags);
57 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertAddCertificateContextToStore(Sys.IntPtr certificateStoreHandle, Sys.IntPtr certificateContext, int addDisposition, out Sys.IntPtr storeContextPtr);
58 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool CertSetCertificateContextProperty(Sys.IntPtr certificateContext, int propertyId, int flags, [SysInterop.In] ref MdPFX.CryptKeyProviderInformation data);
59 [SysInterop.DllImport(MdPFX.DLL_Crypt, SetLastError = true, ExactSpelling = true)][return: SysInterop.MarshalAs(SysInterop.UnmanagedType.Bool)] private static extern bool PFXExportCertStoreEx(Sys.IntPtr certificateStoreHandle, ref MdPFX.CryptoApiBlob pfxBlob, Sys.IntPtr password, Sys.IntPtr reserved, int flags);
60 private static void Check(bool nativeCallSucceeded) { if (!nativeCallSucceeded) { SysInterop.Marshal.ThrowExceptionForHR(SysInterop.Marshal.GetHRForLastWin32Error()); } }
61
62 private static MdPFX.SystemTime ToSystemTime(Sys.DateTime dateTime)
63 {
64 long fileTime = dateTime.ToFileTime();
65 MdPFX.SystemTime systemTime = default(MdPFX.SystemTime);
66 MdPFX.Check(MdPFX.FileTimeToSystemTime(ref fileTime, out systemTime));
67 return systemTime;
68 }
69 #endregion
70
71 public static byte[] Create(string commonName, Sys.DateTime startTime, Sys.DateTime endTime, Sys.Security.SecureString password)
72 {
73 byte[] pfxData;
74 if (commonName == null) { commonName = string.Empty; }
75 MdPFX.SystemTime startSystemTime = MdPFX.ToSystemTime(startTime);
76 MdPFX.SystemTime endSystemTime = MdPFX.ToSystemTime(endTime);
77 string containerName = Sys.Guid.NewGuid().ToString();
78 SysInterop.GCHandle dataHandle = default(SysInterop.GCHandle);
79 Sys.IntPtr providerContext = Sys.IntPtr.Zero;
80 Sys.IntPtr cryptKey = Sys.IntPtr.Zero;
81 Sys.IntPtr certContext = Sys.IntPtr.Zero;
82 Sys.IntPtr certStore = Sys.IntPtr.Zero;
83 Sys.IntPtr storeCertContext = Sys.IntPtr.Zero;
84 Sys.IntPtr passwordPtr = Sys.IntPtr.Zero;
85 Sys.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
86 try
87 {
88 MdPFX.Check(MdPFX.CryptAcquireContextW(out providerContext, containerName, null, 1, 8));
89 MdPFX.Check(MdPFX.CryptGenKey(providerContext, 1, 1, out cryptKey));
90 Sys.IntPtr errorStringPtr = Sys.IntPtr.Zero;
91 int nameDataLength = 0;
92 byte[] nameData = null;
93 dataHandle = SysInterop.GCHandle.Alloc(commonName, SysInterop.GCHandleType.Pinned);
94 if (!MdPFX.CertStrToNameW(0x00010001, dataHandle.AddrOfPinnedObject(), 3, Sys.IntPtr.Zero, null, ref nameDataLength, out errorStringPtr)) { throw new Sys.ArgumentException(SysInterop.Marshal.PtrToStringUni(errorStringPtr)); }
95 nameData = new byte[nameDataLength];
96 if (!MdPFX.CertStrToNameW(0x00010001, dataHandle.AddrOfPinnedObject(), 3, Sys.IntPtr.Zero, nameData, ref nameDataLength, out errorStringPtr)) { throw new Sys.ArgumentException(SysInterop.Marshal.PtrToStringUni(errorStringPtr)); }
97 dataHandle.Free();
98 dataHandle = SysInterop.GCHandle.Alloc(nameData, SysInterop.GCHandleType.Pinned);
99 MdPFX.CryptoApiBlob nameBlob = new MdPFX.CryptoApiBlob(nameData.Length, dataHandle.AddrOfPinnedObject());
100 MdPFX.CryptKeyProviderInformation kpi = new MdPFX.CryptKeyProviderInformation();
101 kpi.ContainerName = containerName;
102 kpi.ProviderType = 1;
103 kpi.KeySpec = 1;
104 certContext = MdPFX.CertCreateSelfSignCertificate(providerContext, ref nameBlob, 0, ref kpi, Sys.IntPtr.Zero, ref startSystemTime, ref endSystemTime, Sys.IntPtr.Zero);
105 MdPFX.Check(certContext != Sys.IntPtr.Zero);
106 dataHandle.Free();
107 certStore = MdPFX.CertOpenStore("Memory", 0, Sys.IntPtr.Zero, 0x2000, Sys.IntPtr.Zero);
108 MdPFX.Check(certStore != Sys.IntPtr.Zero);
109 MdPFX.Check(MdPFX.CertAddCertificateContextToStore(certStore, certContext, 1, out storeCertContext));
110 MdPFX.CertSetCertificateContextProperty(storeCertContext, 2, 0, ref kpi);
111 if (password != null) { passwordPtr = SysInterop.Marshal.SecureStringToCoTaskMemUnicode(password); }
112 MdPFX.CryptoApiBlob pfxBlob = new MdPFX.CryptoApiBlob();
113 MdPFX.Check(MdPFX.PFXExportCertStoreEx(certStore, ref pfxBlob, passwordPtr, Sys.IntPtr.Zero, 7));
114 pfxData = new byte[pfxBlob.DataLength];
115 dataHandle = SysInterop.GCHandle.Alloc(pfxData, SysInterop.GCHandleType.Pinned);
116 pfxBlob.Data = dataHandle.AddrOfPinnedObject();
117 MdPFX.Check(MdPFX.PFXExportCertStoreEx(certStore, ref pfxBlob, passwordPtr, Sys.IntPtr.Zero, 7));
118 dataHandle.Free();
119 }
120 finally
121 {
122 if (passwordPtr != Sys.IntPtr.Zero) { SysInterop.Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr); }
123 if (dataHandle.IsAllocated) { dataHandle.Free(); }
124 if (certContext != Sys.IntPtr.Zero) { MdPFX.CertFreeCertificateContext(certContext); }
125 if (storeCertContext != Sys.IntPtr.Zero) { MdPFX.CertFreeCertificateContext(storeCertContext); }
126 if (certStore != Sys.IntPtr.Zero) { MdPFX.CertCloseStore(certStore, 0); }
127 if (cryptKey != Sys.IntPtr.Zero) { MdPFX.CryptDestroyKey(cryptKey); }
128 if (providerContext != Sys.IntPtr.Zero)
129 {
130 MdPFX.CryptReleaseContext(providerContext, 0);
131 MdPFX.CryptAcquireContextW(out providerContext, containerName, null, 1, 0x10);
132 }
133 }
134 return pfxData;
135 }
136
137 public static Sys.Security.SecureString CreateSecurePassword(string insecurePassword)
138 {
139 if (!string.IsNullOrEmpty(insecurePassword))
140 {
141 Sys.Security.SecureString password = new Sys.Security.SecureString();
142 foreach (char ch in insecurePassword) { password.AppendChar(ch); }
143 password.MakeReadOnly();
144 return password;
145 } else { return null; }
146 }
147
148 public static byte[] Create(string commonName, Sys.DateTime startTime, Sys.DateTime endTime, string insecurePassword)
149 {
150 byte[] pfxData;
151 Sys.Security.SecureString password = null;
152 try
153 {
154 password = MdPFX.CreateSecurePassword(insecurePassword);
155 pfxData = MdPFX.Create(commonName, startTime, endTime, password);
156 } finally { if (password != null) { password.Dispose(); } }
157 return pfxData;
158 }
159
160 public static byte[] Create(string commonName, int YearsValid, Sys.Security.SecureString password)
161 {
162 if (!commonName.StartsWith("CN=", Sys.StringComparison.OrdinalIgnoreCase)) { commonName = "CN=" + commonName; }
163 return MdPFX.Create(commonName, Sys.DateTime.Now, Sys.DateTime.Now.AddYears(YearsValid), password);
164 }
165
166 public static void Create(Sys.IO.Stream save, string commonName, int YearsValid, Sys.Security.SecureString password)
167 {
168 byte[] certificateData = MdPFX.Create(commonName, 5, password);
169 using (Sys.IO.BinaryWriter binWriter = new Sys.IO.BinaryWriter(save))
170 {
171 binWriter.Write(certificateData);
172 binWriter.Flush();
173 }
174 }
175
176 public static byte[] Create(string commonName, Sys.DateTime startTime, Sys.DateTime endTime) { return MdPFX.Create(commonName, startTime, endTime, (Sys.Security.SecureString)null); }
177 public static byte[] Create(string commonName, int YearsValid, string insecurePassword) { using (Sys.Security.SecureString password = MdPFX.CreateSecurePassword(insecurePassword)) { return MdPFX.Create(commonName, YearsValid, password); } }
178 public static void Create(Sys.IO.Stream save, string commonName, int YearsValid, string insecurePassword) { using (Sys.Security.SecureString password = MdPFX.CreateSecurePassword(insecurePassword)) { MdPFX.Create(save, commonName, YearsValid, password); } }
179 public static void Create(string savePath, string commonName, int YearsValid, Sys.Security.SecureString password) { using (Sys.IO.FileStream fStream = Sys.IO.File.Open(savePath, Sys.IO.FileMode.Create)) { MdPFX.Create(fStream, commonName, YearsValid, password); } }
180 public static void Create(string savePath, string commonName, int YearsValid, string insecurePassword) { using (Sys.Security.SecureString password = MdPFX.CreateSecurePassword(insecurePassword)) { using (Sys.IO.FileStream fStream = Sys.IO.File.Open(savePath, Sys.IO.FileMode.Create)) { MdPFX.Create(fStream, commonName, YearsValid, password); } } }
181
182 public static byte[] Create(SysCry509.X509Certificate2 certificate, string insecurePassword, SysCry509.X509Certificate2 signingCert, SysCry509.X509Certificate2Collection chain = null)
183 {
184 SysCry509.X509Certificate2Collection col = new SysCry509.X509Certificate2Collection(certificate);
185 if (chain != null) { col.AddRange(chain); }
186 if (signingCert != null)
187 {
188 SysCry509.X509Certificate2 sigCertNoPK = new SysCry509.X509Certificate2(signingCert.Export(SysCry509.X509ContentType.Cert));
189 col.Add(sigCertNoPK);
190 }
191 return col.Export(SysCry509.X509ContentType.Pfx, insecurePassword);
192 }
193
194 public static byte[] Create(string commonName, string insecurePassword, int YearsValid, SysCry509.X509Certificate2 signingCert, SysCry509.X509Certificate2Collection chain = null)
195 {
196 SysCry509.X509Certificate2 certificate = new SysCry509.X509Certificate2();
197 certificate.Import(MdPFX.Create(commonName, YearsValid, insecurePassword), insecurePassword, (SysCry509.X509KeyStorageFlags.PersistKeySet | SysCry509.X509KeyStorageFlags.Exportable));
198 return MdPFX.Create(certificate, insecurePassword, signingCert, chain: chain);
199 }
200
201 public static SysCry509.X509Certificate2 Load(byte[] rawData, string insecurePassword)
202 {
203 try
204 {
205 SysCry509.X509Certificate2 rCert = new SysCry509.X509Certificate2();
206 rCert.Import(rawData, insecurePassword, (SysCry509.X509KeyStorageFlags.PersistKeySet | SysCry509.X509KeyStorageFlags.Exportable));
207 return rCert;
208 } catch { return null; }
209 }
210
211 public static byte[] Create(string commonName, string insecurePassword, int YearsValid, bool Signed, SysCry509.X509Certificate2Collection chain = null)
212 {
213 if (Signed)
214 {
215 SysCry509.X509Store store = new SysCry509.X509Store(typeof(MdPFX).FullName, SysCry509.StoreLocation.LocalMachine);
216 store.Open(SysCry509.OpenFlags.ReadWrite);
217 const string rCertN = "A.Root.Cert.Name";
218 SysCry509.X509Certificate2 rCert = null;
219 if (store.Certificates.Count > 0) { foreach (SysCry509.X509Certificate2 c in store.Certificates) { if (c.SubjectName.Name == rCertN) { rCert = c; break; } } }
220 if (rCert == null)
221 {
222 rCert = MdPFX.Load(MdPFX.Create(rCertN, 10, "A.Root.Cert.Pass"), "A.Root.Cert.Pass");
223 store.Add(rCert);
224 }
225 store.Close();
226 return MdPFX.Create(commonName, insecurePassword, YearsValid, rCert, chain: chain);
227 } else { return MdPFX.Create(commonName, YearsValid, insecurePassword); }
228 }
229}
230internal static class Program
231{
232 internal static void Main()
233 {
234 Sys.IO.File.WriteAllBytes("C:\\Users\\User\\Desktop\\cert.pfx", MdPFX.Create("My.Name", "Pass.123", 10, true, chain: null));
235 }
236}
237File.WriteAllBytes("C:\\signed.pfx", cert.Export(X509ContentType.Pfx, "pwdpwdpwd"));
238
Then i imported the certificate, and still isn't exact: i'll post the generated certificate (image) and one that is "right" down below - the windows screen is in portuguese (since it's my OS language), but is the "Certificate Path" tab of each certiciate.
The certificate created from the sample code outed this:
But should be like this:
ANSWER
Answered 2021-Dec-26 at 12:52I would say aim for these qualities in development certificates:
- A root certificate authority file, eg
myRoot.ca
- A password protected PKCS12 file (containing a private key + certificate), whose root is the above CA, eg
mySslCert p12
.
- The latter can also be a wildcard certificate, eg usable for multiple subdomains under
*.mycompany.com
, which is useful in terrms of simple administration.
CREATION
Personally I prefer to use OpenSSL to create certs, since this is the technology that secures the internet, and I am then sure that there is nothing technology specific about certs issued.
See my certificates repository and the makeCerts.sh
file, for sone OpenSSL commands:
- Create Root CA keypair
- Create Root certificate
- Create SSL keypair
- Create SSL certificate signing request (which can be for a wildcard certificate)
- Create SSL certificate
- Create password protected PKCS12 file
If you want to use C# to create certs, then you need to follow the same 6 steps and produce the same files. Hopefully this makes your requirements clearer.
DEPLOYMENT
In real environments these days, you may end up deploying the Root CA file (mycompany.ca.pem in my example) and the PKCS12 file (mycompany.ssl.p12 in my example).
This is quite common in Private PKI setups within a private network, so it can be very useful to simulate on a Developer PC. My .NET Example API uses the certs issued, though in some cases I use tools such as cert-manager to automate the issuing.
QUESTION
When upgrading to .NET 6, Web Project throws runtime exception
Asked 2022-Jan-05 at 21:36Using an existing .NET 5 MVC Web App, I attempted to upgrade to .NET 6, but encountered this error. I am also using IIS for Windows Authentication--now setup in .NET 6 as "profiles" under Properties -> Debug -> hyperlink (Open debug launch profiles UI). I also included the newer "Microsoft.AspNetCore.Authentication.Negotiate" Nuget package (and associated code) to handle the newer Windows Authentication library.
When the web app launches, I get the following error:
An unhandled exception occurred while processing the request.
InvalidOperationException: Cannot find compilation library location for package 'System.Security.Cryptography.Pkcs'
Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths(ICompilationAssemblyResolver resolver, List assemblies) Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths() Microsoft.AspNetCore.Mvc.ApplicationParts.AssemblyPartExtensions+<>c.b__0_0(CompilationLibrary library) System.Linq.Enumerable+SelectManySingleSelectorIterator<TSource, TResult>.MoveNext()
...
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
This does NOT go away if I add the package listed: System.Security.Cryptography.Pkcs
ANSWER
Answered 2022-Jan-05 at 21:36I needed to remove at least 1 Nuget package:
- Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation -- I removed this one second, but it started working after I did.
- Microsoft.Extensions.Hosting -- I removed this one first, but this alone did not fix it. I don't know if this "also" needed to be removed. I assume not, but I'm including, just in case. Removing it did not hurt anything.
Edit: As a WARNING, this will lose the abilities given by Razor.RuntimeCompilation. However, there appears to be a code incompatibility with, I believe, IIS and Razor in .NET 6.
QUESTION
Why are signatures created with ecdsa Python library not valid with coincurve?
Asked 2021-Dec-25 at 14:41I'm switching from the pure Python ecdsa
library to the much faster coincurve
library for signing data. I would also like to switch to coincurve
for verifying the signatures (including the old signatures created by the ecdsa
library).
It appears that signatures created with ecdsa
are not (always?) valid in coincurve
. Could someone please explain why this is not working? Also, it seems that cryptography
library is able to validate both ecdsa
signatures and coincurve
signatures without issues, consistently.
What is even more confusing, if you run below script a few times, is that sometimes it prints point 3 and other times it does not. Why would coincurve
only occasionally find the signature valid?
1pip install ecdsa cryptography coincurve
2
1pip install ecdsa cryptography coincurve
2import ecdsa
3import hashlib
4import coincurve
5from coincurve.ecdsa import deserialize_compact, cdata_to_der
6from cryptography.hazmat.primitives import hashes
7from cryptography.hazmat.primitives.asymmetric import ec
8from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
9
10ecdsa_private_key = ecdsa.SigningKey.generate(ecdsa.SECP256k1, None, hashlib.sha256)
11ecdsa_pub = ecdsa_private_key.get_verifying_key()
12message = b"Hello world!"
13digest = hashlib.sha256(message).digest()
14serialized_signature = ecdsa_private_key.sign_digest_deterministic(digest, hashfunc=hashlib.sha256)
15
16signature = cdata_to_der(deserialize_compact(serialized_signature))
17cc_private_key = coincurve.PrivateKey(ecdsa_private_key.to_string())
18cc_pub = cc_private_key.public_key
19crypto_pub = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256K1(), cc_pub.format(True))
20
21if ecdsa_pub.verify_digest(serialized_signature, digest) is True:
22 print("1. ecdsa can validate its own signature")
23
24crypto_pub.verify(signature, digest, ec.ECDSA(Prehashed(hashes.SHA256())))
25print("2. cryptography can validate ecdsa signature (raises exception if not valid)")
26
27if cc_pub.verify(signature, digest, None) is False:
28 print("3. coincurve will not validate ecdsa signature")
29
30signature = cc_private_key.sign(digest, None)
31
32crypto_pub.verify(signature, digest, ec.ECDSA(Prehashed(hashes.SHA256())))
33print("4. cryptography can validate coincurve signature (raises exception if not valid)")
34
35if cc_pub.verify(signature, digest, None) is True:
36 print("5. coincurve will validate its own signature")
37
ANSWER
Answered 2021-Dec-25 at 14:41Bitcoin and the coincurve library use canonical signatures while this is not true for the ecdsa library.
What does canonical signature mean?
In general, if (r,s)
is a valid signature, then (r,s') := (r,-s mod n)
is also a valid signature (n
is the order of the base point).
A canonical signature uses the value s' = -s mod n = n - s
instead of s
, i.e. the signature (r, n-s)
, if s > n/2
, s. e.g. here.
All signatures from the ecdsa library that were not been successfully validated by the coincurve library in your test program have an s > n/2
and thus are not canonical, whereas those that were successfully validated are canonical.
So the fix is simply to canonize the signature of the ecdsa library, e.g.:
1pip install ecdsa cryptography coincurve
2import ecdsa
3import hashlib
4import coincurve
5from coincurve.ecdsa import deserialize_compact, cdata_to_der
6from cryptography.hazmat.primitives import hashes
7from cryptography.hazmat.primitives.asymmetric import ec
8from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
9
10ecdsa_private_key = ecdsa.SigningKey.generate(ecdsa.SECP256k1, None, hashlib.sha256)
11ecdsa_pub = ecdsa_private_key.get_verifying_key()
12message = b"Hello world!"
13digest = hashlib.sha256(message).digest()
14serialized_signature = ecdsa_private_key.sign_digest_deterministic(digest, hashfunc=hashlib.sha256)
15
16signature = cdata_to_der(deserialize_compact(serialized_signature))
17cc_private_key = coincurve.PrivateKey(ecdsa_private_key.to_string())
18cc_pub = cc_private_key.public_key
19crypto_pub = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256K1(), cc_pub.format(True))
20
21if ecdsa_pub.verify_digest(serialized_signature, digest) is True:
22 print("1. ecdsa can validate its own signature")
23
24crypto_pub.verify(signature, digest, ec.ECDSA(Prehashed(hashes.SHA256())))
25print("2. cryptography can validate ecdsa signature (raises exception if not valid)")
26
27if cc_pub.verify(signature, digest, None) is False:
28 print("3. coincurve will not validate ecdsa signature")
29
30signature = cc_private_key.sign(digest, None)
31
32crypto_pub.verify(signature, digest, ec.ECDSA(Prehashed(hashes.SHA256())))
33print("4. cryptography can validate coincurve signature (raises exception if not valid)")
34
35if cc_pub.verify(signature, digest, None) is True:
36 print("5. coincurve will validate its own signature")
37def canonize(s_bytes):
38 n = 115792089237316195423570985008687907852837564279074904382605163141518161494337
39 s = int.from_bytes(s_bytes, byteorder='big')
40 if s > n//2:
41 s = n - s
42 return s.to_bytes(32, byteorder='big')
43
44...
45serialized_signature = serialized_signature[:32] + canonize(serialized_signature[32:]) # Fix: canonize
46signature = cdata_to_der(deserialize_compact(serialized_signature))
47...
48
With this fix, the coincurve library successfully validates all signatures from the ecdsa library in your test program.
QUESTION
Signing payload in JS (Frontend) using EC and validating in Python
Asked 2021-Dec-18 at 11:56I have a Python backend that generates public/private keys, generates a payload, then needs to get that payload signed by the client (ReactJS or pure JS), which is later verified.
The implementation in Python looks like this:
Imports
1import json
2import uuid
3
4from backend.config import STARTING_BALANCE
5from cryptography.hazmat.backends import default_backend
6from cryptography.hazmat.primitives.asymmetric import ec
7from cryptography.hazmat.primitives.asymmetric.utils import (
8 encode_dss_signature,
9 decode_dss_signature
10)
11from cryptography.hazmat.primitives import hashes, serialization
12from cryptography.exceptions import InvalidSignature
13
14from cryptography.hazmat.primitives.serialization import load_pem_private_key
15
16import base64
17import hashlib
18
Generate keys:
1import json
2import uuid
3
4from backend.config import STARTING_BALANCE
5from cryptography.hazmat.backends import default_backend
6from cryptography.hazmat.primitives.asymmetric import ec
7from cryptography.hazmat.primitives.asymmetric.utils import (
8 encode_dss_signature,
9 decode_dss_signature
10)
11from cryptography.hazmat.primitives import hashes, serialization
12from cryptography.exceptions import InvalidSignature
13
14from cryptography.hazmat.primitives.serialization import load_pem_private_key
15
16import base64
17import hashlib
18class User:
19 def __init__(self):
20 self.address = hashlib.sha1(str(str(uuid.uuid4())[0:8]).encode("UTF-8")).hexdigest()
21 self.private_key = ec.generate_private_key(
22 ec.SECP256K1(),
23
24 default_backend()
25 )
26
27 self.private_key_return = self.private_key.private_bytes(
28 encoding=serialization.Encoding.PEM,
29 format=serialization.PrivateFormat.TraditionalOpenSSL,
30 encryption_algorithm=serialization.NoEncryption()
31 )
32
33 self.public_key = self.private_key.public_key()
34
35 self.serialize_public_key()
36
37 def serialize_public_key():
38 """
39 Reset the public key to its serialized version.
40 """
41 self.public_key = self.public_key.public_bytes(
42 encoding=serialization.Encoding.PEM,
43 format=serialization.PublicFormat.SubjectPublicKeyInfo
44 ).decode('utf-8')
45
Sign:
1import json
2import uuid
3
4from backend.config import STARTING_BALANCE
5from cryptography.hazmat.backends import default_backend
6from cryptography.hazmat.primitives.asymmetric import ec
7from cryptography.hazmat.primitives.asymmetric.utils import (
8 encode_dss_signature,
9 decode_dss_signature
10)
11from cryptography.hazmat.primitives import hashes, serialization
12from cryptography.exceptions import InvalidSignature
13
14from cryptography.hazmat.primitives.serialization import load_pem_private_key
15
16import base64
17import hashlib
18class User:
19 def __init__(self):
20 self.address = hashlib.sha1(str(str(uuid.uuid4())[0:8]).encode("UTF-8")).hexdigest()
21 self.private_key = ec.generate_private_key(
22 ec.SECP256K1(),
23
24 default_backend()
25 )
26
27 self.private_key_return = self.private_key.private_bytes(
28 encoding=serialization.Encoding.PEM,
29 format=serialization.PrivateFormat.TraditionalOpenSSL,
30 encryption_algorithm=serialization.NoEncryption()
31 )
32
33 self.public_key = self.private_key.public_key()
34
35 self.serialize_public_key()
36
37 def serialize_public_key():
38 """
39 Reset the public key to its serialized version.
40 """
41 self.public_key = self.public_key.public_bytes(
42 encoding=serialization.Encoding.PEM,
43 format=serialization.PublicFormat.SubjectPublicKeyInfo
44 ).decode('utf-8')
45def sign(self, data):
46 """
47 Generate a signature based on the data using the local private key.
48 """
49 return decode_dss_signature(self.private_key.sign(
50 json.dumps(data).encode('utf-8'),
51 ec.ECDSA(hashes.SHA256())
52 ))
53
Verify:
1import json
2import uuid
3
4from backend.config import STARTING_BALANCE
5from cryptography.hazmat.backends import default_backend
6from cryptography.hazmat.primitives.asymmetric import ec
7from cryptography.hazmat.primitives.asymmetric.utils import (
8 encode_dss_signature,
9 decode_dss_signature
10)
11from cryptography.hazmat.primitives import hashes, serialization
12from cryptography.exceptions import InvalidSignature
13
14from cryptography.hazmat.primitives.serialization import load_pem_private_key
15
16import base64
17import hashlib
18class User:
19 def __init__(self):
20 self.address = hashlib.sha1(str(str(uuid.uuid4())[0:8]).encode("UTF-8")).hexdigest()
21 self.private_key = ec.generate_private_key(
22 ec.SECP256K1(),
23
24 default_backend()
25 )
26
27 self.private_key_return = self.private_key.private_bytes(
28 encoding=serialization.Encoding.PEM,
29 format=serialization.PrivateFormat.TraditionalOpenSSL,
30 encryption_algorithm=serialization.NoEncryption()
31 )
32
33 self.public_key = self.private_key.public_key()
34
35 self.serialize_public_key()
36
37 def serialize_public_key():
38 """
39 Reset the public key to its serialized version.
40 """
41 self.public_key = self.public_key.public_bytes(
42 encoding=serialization.Encoding.PEM,
43 format=serialization.PublicFormat.SubjectPublicKeyInfo
44 ).decode('utf-8')
45def sign(self, data):
46 """
47 Generate a signature based on the data using the local private key.
48 """
49 return decode_dss_signature(self.private_key.sign(
50 json.dumps(data).encode('utf-8'),
51 ec.ECDSA(hashes.SHA256())
52 ))
53@staticmethod
54def verify(public_key, data, signature):
55 """
56 Verify a signature based on the original public key and data.
57 """
58 deserialized_public_key = serialization.load_pem_public_key(
59 public_key.encode('utf-8'),
60 default_backend()
61 )
62
63 (r, s) = signature
64
65 try:
66 deserialized_public_key.verify(
67 encode_dss_signature(r, s),
68 json.dumps(data).encode('utf-8'),
69 ec.ECDSA(hashes.SHA256())
70 )
71 return True
72 except InvalidSignature:
73 return False
74
What I need now is to load (or even generate) the PEM keys on the client-side, then upon request, sign a JSON payload that can later be verified from the Python backend.
I tried looking into the usage of web cryptography and cryptoJS but had no luck.
I'm okay using another algorithm that is more compatible, but at the very least I need the signing functionality fully working.
I also tried compiling Python to JS using Brython and Pyodide but both could not support all the required packages.
In simple terms, I am looking for the following:
Generate Payload (Python) -----> Sign Payload (JS) -----> Verify Signature (Python)
Any help/advice would be greatly appreciated.
ANSWER
Answered 2021-Dec-18 at 11:56CryptoJS only supports symmetric encryption and therefore not ECDSA. WebCrypto supports ECDSA, but not secp256k1.
WebCrypto has the advantage that it is supported by all major browsers. Since you can use other curves according to your comment, I will describe a solution with a curve supported by WebCrypto.
Otherwise, sjcl would also be an alternative, a pure JavaScript library that supports ECDSA and especially secp256k1, s.here.
WebCrypto is a low level API that provides the functionality you need like key generation, key export and signing. Regarding ECDSA WebCrypto supports the curves P-256 (aka secp256r1), P-384 (aka secp384r1) and p-521 (aka secp521r1). In the following I use P-256.
The following JavaScript code generates a key pair for P-256, exports the public key in X.509/SPKI format, DER encoded (so it can be sent to the Python site), and signs a message:
1import json
2import uuid
3
4from backend.config import STARTING_BALANCE
5from cryptography.hazmat.backends import default_backend
6from cryptography.hazmat.primitives.asymmetric import ec
7from cryptography.hazmat.primitives.asymmetric.utils import (
8 encode_dss_signature,
9 decode_dss_signature
10)
11from cryptography.hazmat.primitives import hashes, serialization
12from cryptography.exceptions import InvalidSignature
13
14from cryptography.hazmat.primitives.serialization import load_pem_private_key
15
16import base64
17import hashlib
18class User:
19 def __init__(self):
20 self.address = hashlib.sha1(str(str(uuid.uuid4())[0:8]).encode("UTF-8")).hexdigest()
21 self.private_key = ec.generate_private_key(
22 ec.SECP256K1(),
23
24 default_backend()
25 )
26
27 self.private_key_return = self.private_key.private_bytes(
28 encoding=serialization.Encoding.PEM,
29 format=serialization.PrivateFormat.TraditionalOpenSSL,
30 encryption_algorithm=serialization.NoEncryption()
31 )
32
33 self.public_key = self.private_key.public_key()
34
35 self.serialize_public_key()
36
37 def serialize_public_key():
38 """
39 Reset the public key to its serialized version.
40 """
41 self.public_key = self.public_key.public_bytes(
42 encoding=serialization.Encoding.PEM,
43 format=serialization.PublicFormat.SubjectPublicKeyInfo
44 ).decode('utf-8')
45def sign(self, data):
46 """
47 Generate a signature based on the data using the local private key.
48 """
49 return decode_dss_signature(self.private_key.sign(
50 json.dumps(data).encode('utf-8'),
51 ec.ECDSA(hashes.SHA256())
52 ))
53@staticmethod
54def verify(public_key, data, signature):
55 """
56 Verify a signature based on the original public key and data.
57 """
58 deserialized_public_key = serialization.load_pem_public_key(
59 public_key.encode('utf-8'),
60 default_backend()
61 )
62
63 (r, s) = signature
64
65 try:
66 deserialized_public_key.verify(
67 encode_dss_signature(r, s),
68 json.dumps(data).encode('utf-8'),
69 ec.ECDSA(hashes.SHA256())
70 )
71 return True
72 except InvalidSignature:
73 return False
74(async () => {
75
76 // Generate key pair
77 var keypair = await window.crypto.subtle.generateKey(
78 {
79 name: "ECDSA",
80 namedCurve: "P-256", // secp256r1
81 },
82 false,
83 ["sign", "verify"]
84 );
85
86 // Export public key in X.509/SPKI format, DER encoded
87 var publicKey = await window.crypto.subtle.exportKey(
88 "spki",
89 keypair.publicKey
90 );
91 document.getElementById("pub").innerHTML = "Public key: " + ab2b64(publicKey);
92
93 // Sign data
94 var data = {
95 "data_1":"The quick brown fox",
96 "data_2":"jumps over the lazy dog"
97 }
98 var dataStr = JSON.stringify(data)
99 var dataBuf = new TextEncoder().encode(dataStr).buffer
100 var signature = await window.crypto.subtle.sign(
101 {
102 name: "ECDSA",
103 hash: {name: "SHA-256"},
104 },
105 keypair.privateKey,
106 dataBuf
107 );
108 document.getElementById("sig").innerHTML = "Signature: " + ab2b64(signature);
109
110})();
111
112// Helper
113function ab2b64(arrayBuffer) {
114 return window.btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
115}
1import json
2import uuid
3
4from backend.config import STARTING_BALANCE
5from cryptography.hazmat.backends import default_backend
6from cryptography.hazmat.primitives.asymmetric import ec
7from cryptography.hazmat.primitives.asymmetric.utils import (
8 encode_dss_signature,
9 decode_dss_signature
10)
11from cryptography.hazmat.primitives import hashes, serialization
12from cryptography.exceptions import InvalidSignature
13
14from cryptography.hazmat.primitives.serialization import load_pem_private_key
15
16import base64
17import hashlib
18class User:
19 def __init__(self):
20 self.address = hashlib.sha1(str(str(uuid.uuid4())[0:8]).encode("UTF-8")).hexdigest()
21 self.private_key = ec.generate_private_key(
22 ec.SECP256K1(),
23
24 default_backend()
25 )
26
27 self.private_key_return = self.private_key.private_bytes(
28 encoding=serialization.Encoding.PEM,
29 format=serialization.PrivateFormat.TraditionalOpenSSL,
30 encryption_algorithm=serialization.NoEncryption()
31 )
32
33 self.public_key = self.private_key.public_key()
34
35 self.serialize_public_key()
36
37 def serialize_public_key():
38 """
39 Reset the public key to its serialized version.
40 """
41 self.public_key = self.public_key.public_bytes(
42 encoding=serialization.Encoding.PEM,
43 format=serialization.PublicFormat.SubjectPublicKeyInfo
44 ).decode('utf-8')
45def sign(self, data):
46 """
47 Generate a signature based on the data using the local private key.
48 """
49 return decode_dss_signature(self.private_key.sign(
50 json.dumps(data).encode('utf-8'),
51 ec.ECDSA(hashes.SHA256())
52 ))
53@staticmethod
54def verify(public_key, data, signature):
55 """
56 Verify a signature based on the original public key and data.
57 """
58 deserialized_public_key = serialization.load_pem_public_key(
59 public_key.encode('utf-8'),
60 default_backend()
61 )
62
63 (r, s) = signature
64
65 try:
66 deserialized_public_key.verify(
67 encode_dss_signature(r, s),
68 json.dumps(data).encode('utf-8'),
69 ec.ECDSA(hashes.SHA256())
70 )
71 return True
72 except InvalidSignature:
73 return False
74(async () => {
75
76 // Generate key pair
77 var keypair = await window.crypto.subtle.generateKey(
78 {
79 name: "ECDSA",
80 namedCurve: "P-256", // secp256r1
81 },
82 false,
83 ["sign", "verify"]
84 );
85
86 // Export public key in X.509/SPKI format, DER encoded
87 var publicKey = await window.crypto.subtle.exportKey(
88 "spki",
89 keypair.publicKey
90 );
91 document.getElementById("pub").innerHTML = "Public key: " + ab2b64(publicKey);
92
93 // Sign data
94 var data = {
95 "data_1":"The quick brown fox",
96 "data_2":"jumps over the lazy dog"
97 }
98 var dataStr = JSON.stringify(data)
99 var dataBuf = new TextEncoder().encode(dataStr).buffer
100 var signature = await window.crypto.subtle.sign(
101 {
102 name: "ECDSA",
103 hash: {name: "SHA-256"},
104 },
105 keypair.privateKey,
106 dataBuf
107 );
108 document.getElementById("sig").innerHTML = "Signature: " + ab2b64(signature);
109
110})();
111
112// Helper
113function ab2b64(arrayBuffer) {
114 return window.btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
115}<p style="font-family:'Courier New', monospace;" id="pub"></p>
116<p style="font-family:'Courier New', monospace;" id="sig"></p>
A possible output is:
1import json
2import uuid
3
4from backend.config import STARTING_BALANCE
5from cryptography.hazmat.backends import default_backend
6from cryptography.hazmat.primitives.asymmetric import ec
7from cryptography.hazmat.primitives.asymmetric.utils import (
8 encode_dss_signature,
9 decode_dss_signature
10)
11from cryptography.hazmat.primitives import hashes, serialization
12from cryptography.exceptions import InvalidSignature
13
14from cryptography.hazmat.primitives.serialization import load_pem_private_key
15
16import base64
17import hashlib
18class User:
19 def __init__(self):
20 self.address = hashlib.sha1(str(str(uuid.uuid4())[0:8]).encode("UTF-8")).hexdigest()
21 self.private_key = ec.generate_private_key(
22 ec.SECP256K1(),
23
24 default_backend()
25 )
26
27 self.private_key_return = self.private_key.private_bytes(
28 encoding=serialization.Encoding.PEM,
29 format=serialization.PrivateFormat.TraditionalOpenSSL,
30 encryption_algorithm=serialization.NoEncryption()
31 )
32
33 self.public_key = self.private_key.public_key()
34
35 self.serialize_public_key()
36
37 def serialize_public_key():
38 """
39 Reset the public key to its serialized version.
40 """
41 self.public_key = self.public_key.public_bytes(
42 encoding=serialization.Encoding.PEM,
43 format=serialization.PublicFormat.SubjectPublicKeyInfo
44 ).decode('utf-8')
45def sign(self, data):
46 """
47 Generate a signature based on the data using the local private key.
48 """
49 return decode_dss_signature(self.private_key.sign(
50 json.dumps(data).encode('utf-8'),
51 ec.ECDSA(hashes.SHA256())
52 ))
53@staticmethod
54def verify(public_key, data, signature):
55 """
56 Verify a signature based on the original public key and data.
57 """
58 deserialized_public_key = serialization.load_pem_public_key(
59 public_key.encode('utf-8'),
60 default_backend()
61 )
62
63 (r, s) = signature
64
65 try:
66 deserialized_public_key.verify(
67 encode_dss_signature(r, s),
68 json.dumps(data).encode('utf-8'),
69 ec.ECDSA(hashes.SHA256())
70 )
71 return True
72 except InvalidSignature:
73 return False
74(async () => {
75
76 // Generate key pair
77 var keypair = await window.crypto.subtle.generateKey(
78 {
79 name: "ECDSA",
80 namedCurve: "P-256", // secp256r1
81 },
82 false,
83 ["sign", "verify"]
84 );
85
86 // Export public key in X.509/SPKI format, DER encoded
87 var publicKey = await window.crypto.subtle.exportKey(
88 "spki",
89 keypair.publicKey
90 );
91 document.getElementById("pub").innerHTML = "Public key: " + ab2b64(publicKey);
92
93 // Sign data
94 var data = {
95 "data_1":"The quick brown fox",
96 "data_2":"jumps over the lazy dog"
97 }
98 var dataStr = JSON.stringify(data)
99 var dataBuf = new TextEncoder().encode(dataStr).buffer
100 var signature = await window.crypto.subtle.sign(
101 {
102 name: "ECDSA",
103 hash: {name: "SHA-256"},
104 },
105 keypair.privateKey,
106 dataBuf
107 );
108 document.getElementById("sig").innerHTML = "Signature: " + ab2b64(signature);
109
110})();
111
112// Helper
113function ab2b64(arrayBuffer) {
114 return window.btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
115}<p style="font-family:'Courier New', monospace;" id="pub"></p>
116<p style="font-family:'Courier New', monospace;" id="sig"></p>Public key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWzC5lPNifcHNuKL+/jjhrtTi+9gAMbYui9Vv7TjtS7RCt8p6Y6zUmHVpGEowuVMuOSNxfpJYpnGExNT/eWhuwQ==
117Signature: XRNTbkHK7H8XPEIJQhS6K6ncLPEuWWrkXLXiNWwv6ImnL2Dm5VHcazJ7QYQNOvWJmB2T3rconRkT0N4BDFapCQ==
118
On the Python side a successful verification would be possible with:
1import json
2import uuid
3
4from backend.config import STARTING_BALANCE
5from cryptography.hazmat.backends import default_backend
6from cryptography.hazmat.primitives.asymmetric import ec
7from cryptography.hazmat.primitives.asymmetric.utils import (
8 encode_dss_signature,
9 decode_dss_signature
10)
11from cryptography.hazmat.primitives import hashes, serialization
12from cryptography.exceptions import InvalidSignature
13
14from cryptography.hazmat.primitives.serialization import load_pem_private_key
15
16import base64
17import hashlib
18class User:
19 def __init__(self):
20 self.address = hashlib.sha1(str(str(uuid.uuid4())[0:8]).encode("UTF-8")).hexdigest()
21 self.private_key = ec.generate_private_key(
22 ec.SECP256K1(),
23
24 default_backend()
25 )
26
27 self.private_key_return = self.private_key.private_bytes(
28 encoding=serialization.Encoding.PEM,
29 format=serialization.PrivateFormat.TraditionalOpenSSL,
30 encryption_algorithm=serialization.NoEncryption()
31 )
32
33 self.public_key = self.private_key.public_key()
34
35 self.serialize_public_key()
36
37 def serialize_public_key():
38 """
39 Reset the public key to its serialized version.
40 """
41 self.public_key = self.public_key.public_bytes(
42 encoding=serialization.Encoding.PEM,
43 format=serialization.PublicFormat.SubjectPublicKeyInfo
44 ).decode('utf-8')
45def sign(self, data):
46 """
47 Generate a signature based on the data using the local private key.
48 """
49 return decode_dss_signature(self.private_key.sign(
50 json.dumps(data).encode('utf-8'),
51 ec.ECDSA(hashes.SHA256())
52 ))
53@staticmethod
54def verify(public_key, data, signature):
55 """
56 Verify a signature based on the original public key and data.
57 """
58 deserialized_public_key = serialization.load_pem_public_key(
59 public_key.encode('utf-8'),
60 default_backend()
61 )
62
63 (r, s) = signature
64
65 try:
66 deserialized_public_key.verify(
67 encode_dss_signature(r, s),
68 json.dumps(data).encode('utf-8'),
69 ec.ECDSA(hashes.SHA256())
70 )
71 return True
72 except InvalidSignature:
73 return False
74(async () => {
75
76 // Generate key pair
77 var keypair = await window.crypto.subtle.generateKey(
78 {
79 name: "ECDSA",
80 namedCurve: "P-256", // secp256r1
81 },
82 false,
83 ["sign", "verify"]
84 );
85
86 // Export public key in X.509/SPKI format, DER encoded
87 var publicKey = await window.crypto.subtle.exportKey(
88 "spki",
89 keypair.publicKey
90 );
91 document.getElementById("pub").innerHTML = "Public key: " + ab2b64(publicKey);
92
93 // Sign data
94 var data = {
95 "data_1":"The quick brown fox",
96 "data_2":"jumps over the lazy dog"
97 }
98 var dataStr = JSON.stringify(data)
99 var dataBuf = new TextEncoder().encode(dataStr).buffer
100 var signature = await window.crypto.subtle.sign(
101 {
102 name: "ECDSA",
103 hash: {name: "SHA-256"},
104 },
105 keypair.privateKey,
106 dataBuf
107 );
108 document.getElementById("sig").innerHTML = "Signature: " + ab2b64(signature);
109
110})();
111
112// Helper
113function ab2b64(arrayBuffer) {
114 return window.btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
115}<p style="font-family:'Courier New', monospace;" id="pub"></p>
116<p style="font-family:'Courier New', monospace;" id="sig"></p>Public key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWzC5lPNifcHNuKL+/jjhrtTi+9gAMbYui9Vv7TjtS7RCt8p6Y6zUmHVpGEowuVMuOSNxfpJYpnGExNT/eWhuwQ==
117Signature: XRNTbkHK7H8XPEIJQhS6K6ncLPEuWWrkXLXiNWwv6ImnL2Dm5VHcazJ7QYQNOvWJmB2T3rconRkT0N4BDFapCQ==
118from cryptography.hazmat.backends import default_backend
119from cryptography.hazmat.primitives.asymmetric import ec
120from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature
121from cryptography.hazmat.primitives.serialization import load_der_public_key
122from cryptography.hazmat.primitives import hashes
123from cryptography.exceptions import InvalidSignature
124import base64
125import json
126
127publikKeyDer = base64.b64decode("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWzC5lPNifcHNuKL+/jjhrtTi+9gAMbYui9Vv7TjtS7RCt8p6Y6zUmHVpGEowuVMuOSNxfpJYpnGExNT/eWhuwQ==")
128data = {
129 "data_1":"The quick brown fox",
130 "data_2":"jumps over the lazy dog"
131}
132signature = base64.b64decode("XRNTbkHK7H8XPEIJQhS6K6ncLPEuWWrkXLXiNWwv6ImnL2Dm5VHcazJ7QYQNOvWJmB2T3rconRkT0N4BDFapCQ==")
133
134publicKey = load_der_public_key(publikKeyDer, default_backend())
135r = int.from_bytes(signature[:32], byteorder='big')
136s = int.from_bytes(signature[32:], byteorder='big')
137
138try:
139 publicKey.verify(
140 encode_dss_signature(r, s),
141 json.dumps(data, separators=(',', ':')).encode('utf-8'),
142 ec.ECDSA(hashes.SHA256())
143 )
144 print("verification succeeded")
145except InvalidSignature:
146 print("verification failed")
147
Where, unlike the posted Python code, load_der_public_key()
is used instead of load_pem_public_key()
.
Also, WebCrypto returns the signature in IEEE P1363 format, but as a concatenated ArrayBuffer
r|s, so a conversion of both parts to an integer is necessary to allow a format conversion to ASN.1/DER with encode_dss_signature()
.
Regarding JSON the separators have to be redefined to the most compact representation (but this depends on the settings on the JavaScript side).
QUESTION
convert base-64 spki string into public key
Asked 2021-Dec-17 at 18:59I'm trying to find a python equivalent of this js function:
1/**
2* Generating the shared secret with the merchant private key and the ephemeral public key(part of the payment token data)
3* using Elliptic Curve Diffie-Hellman (id-ecDH 1.3.132.1.12).
4* As the Apple Pay certificate is issued using prime256v1 encryption, create elliptic curve key instances using the package - https://www.npmjs.com/package/ec-key
5*/
6sharedSecret (privatePem) {
7 const prv = new ECKey(privatePem, 'pem') // Create a new ECkey instance from PEM formatted string
8 const publicEc = new ECKey(this.ephemeralPublicKey, 'spki') // Create a new ECKey instance from a base-64 spki string
9 return prv.computeSecret(publicEc).toString('hex') // Compute secret using private key for provided ephemeral public key
10 }
11
public key i try to convert: (should be a base-64 spki string?)
1/**
2* Generating the shared secret with the merchant private key and the ephemeral public key(part of the payment token data)
3* using Elliptic Curve Diffie-Hellman (id-ecDH 1.3.132.1.12).
4* As the Apple Pay certificate is issued using prime256v1 encryption, create elliptic curve key instances using the package - https://www.npmjs.com/package/ec-key
5*/
6sharedSecret (privatePem) {
7 const prv = new ECKey(privatePem, 'pem') // Create a new ECkey instance from PEM formatted string
8 const publicEc = new ECKey(this.ephemeralPublicKey, 'spki') // Create a new ECKey instance from a base-64 spki string
9 return prv.computeSecret(publicEc).toString('hex') // Compute secret using private key for provided ephemeral public key
10 }
11MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYtpZKqPDqavs4KzNnMoxWdIThKe/ErKMI/l34Y9/xVkt4DU4BrCaQnGLlRGx+Pn/WHPkQg3BYoRH4xUWswNhEA==
12
What i manage to do:
1/**
2* Generating the shared secret with the merchant private key and the ephemeral public key(part of the payment token data)
3* using Elliptic Curve Diffie-Hellman (id-ecDH 1.3.132.1.12).
4* As the Apple Pay certificate is issued using prime256v1 encryption, create elliptic curve key instances using the package - https://www.npmjs.com/package/ec-key
5*/
6sharedSecret (privatePem) {
7 const prv = new ECKey(privatePem, 'pem') // Create a new ECkey instance from PEM formatted string
8 const publicEc = new ECKey(this.ephemeralPublicKey, 'spki') // Create a new ECKey instance from a base-64 spki string
9 return prv.computeSecret(publicEc).toString('hex') // Compute secret using private key for provided ephemeral public key
10 }
11MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYtpZKqPDqavs4KzNnMoxWdIThKe/ErKMI/l34Y9/xVkt4DU4BrCaQnGLlRGx+Pn/WHPkQg3BYoRH4xUWswNhEA==
12from cryptography.hazmat.primitives.asymmetric.ec import SECP256R1, EllipticCurvePublicKey, ECDH
13from cryptography.hazmat.primitives.serialization import load_pem_private_key
14
15def __compute_shared_secret(ephemeral_public_key: str) -> bytes:
16 curve = SECP256R1()
17 key = base64.b64decode(ephemeral_public_key)
18 public_key = EllipticCurvePublicKey.from_encoded_point(curve, key) # problem here
19 server_private_key = load_pem_private_key(<private_key>, password=None)
20 shared_secret = server_private_key.exchange(ECDH(), public_key)
21 return shared_secret
22
1/**
2* Generating the shared secret with the merchant private key and the ephemeral public key(part of the payment token data)
3* using Elliptic Curve Diffie-Hellman (id-ecDH 1.3.132.1.12).
4* As the Apple Pay certificate is issued using prime256v1 encryption, create elliptic curve key instances using the package - https://www.npmjs.com/package/ec-key
5*/
6sharedSecret (privatePem) {
7 const prv = new ECKey(privatePem, 'pem') // Create a new ECkey instance from PEM formatted string
8 const publicEc = new ECKey(this.ephemeralPublicKey, 'spki') // Create a new ECKey instance from a base-64 spki string
9 return prv.computeSecret(publicEc).toString('hex') // Compute secret using private key for provided ephemeral public key
10 }
11MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYtpZKqPDqavs4KzNnMoxWdIThKe/ErKMI/l34Y9/xVkt4DU4BrCaQnGLlRGx+Pn/WHPkQg3BYoRH4xUWswNhEA==
12from cryptography.hazmat.primitives.asymmetric.ec import SECP256R1, EllipticCurvePublicKey, ECDH
13from cryptography.hazmat.primitives.serialization import load_pem_private_key
14
15def __compute_shared_secret(ephemeral_public_key: str) -> bytes:
16 curve = SECP256R1()
17 key = base64.b64decode(ephemeral_public_key)
18 public_key = EllipticCurvePublicKey.from_encoded_point(curve, key) # problem here
19 server_private_key = load_pem_private_key(<private_key>, password=None)
20 shared_secret = server_private_key.exchange(ECDH(), public_key)
21 return shared_secret
22ValueError: Unsupported elliptic curve point type
23
From what i understand i need to convert the public key to something before using it in EllipticCurvePublicKey, but i can't figure what type of conversion i should do.
ANSWER
Answered 2021-Dec-17 at 18:59According to the documentation of the JavaScript library the line
1/**
2* Generating the shared secret with the merchant private key and the ephemeral public key(part of the payment token data)
3* using Elliptic Curve Diffie-Hellman (id-ecDH 1.3.132.1.12).
4* As the Apple Pay certificate is issued using prime256v1 encryption, create elliptic curve key instances using the package - https://www.npmjs.com/package/ec-key
5*/
6sharedSecret (privatePem) {
7 const prv = new ECKey(privatePem, 'pem') // Create a new ECkey instance from PEM formatted string
8 const publicEc = new ECKey(this.ephemeralPublicKey, 'spki') // Create a new ECKey instance from a base-64 spki string
9 return prv.computeSecret(publicEc).toString('hex') // Compute secret using private key for provided ephemeral public key
10 }
11MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYtpZKqPDqavs4KzNnMoxWdIThKe/ErKMI/l34Y9/xVkt4DU4BrCaQnGLlRGx+Pn/WHPkQg3BYoRH4xUWswNhEA==
12from cryptography.hazmat.primitives.asymmetric.ec import SECP256R1, EllipticCurvePublicKey, ECDH
13from cryptography.hazmat.primitives.serialization import load_pem_private_key
14
15def __compute_shared_secret(ephemeral_public_key: str) -> bytes:
16 curve = SECP256R1()
17 key = base64.b64decode(ephemeral_public_key)
18 public_key = EllipticCurvePublicKey.from_encoded_point(curve, key) # problem here
19 server_private_key = load_pem_private_key(<private_key>, password=None)
20 shared_secret = server_private_key.exchange(ECDH(), public_key)
21 return shared_secret
22ValueError: Unsupported elliptic curve point type
23const publicEc = new ECKey(this.ephemeralPublicKey, 'spki')
24
imports a Base64 encoded X.509/SPKI DER key.
In Python, this can be done with load_der_public_key()
of the Cryptography library as follows:
1/**
2* Generating the shared secret with the merchant private key and the ephemeral public key(part of the payment token data)
3* using Elliptic Curve Diffie-Hellman (id-ecDH 1.3.132.1.12).
4* As the Apple Pay certificate is issued using prime256v1 encryption, create elliptic curve key instances using the package - https://www.npmjs.com/package/ec-key
5*/
6sharedSecret (privatePem) {
7 const prv = new ECKey(privatePem, 'pem') // Create a new ECkey instance from PEM formatted string
8 const publicEc = new ECKey(this.ephemeralPublicKey, 'spki') // Create a new ECKey instance from a base-64 spki string
9 return prv.computeSecret(publicEc).toString('hex') // Compute secret using private key for provided ephemeral public key
10 }
11MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYtpZKqPDqavs4KzNnMoxWdIThKe/ErKMI/l34Y9/xVkt4DU4BrCaQnGLlRGx+Pn/WHPkQg3BYoRH4xUWswNhEA==
12from cryptography.hazmat.primitives.asymmetric.ec import SECP256R1, EllipticCurvePublicKey, ECDH
13from cryptography.hazmat.primitives.serialization import load_pem_private_key
14
15def __compute_shared_secret(ephemeral_public_key: str) -> bytes:
16 curve = SECP256R1()
17 key = base64.b64decode(ephemeral_public_key)
18 public_key = EllipticCurvePublicKey.from_encoded_point(curve, key) # problem here
19 server_private_key = load_pem_private_key(<private_key>, password=None)
20 shared_secret = server_private_key.exchange(ECDH(), public_key)
21 return shared_secret
22ValueError: Unsupported elliptic curve point type
23const publicEc = new ECKey(this.ephemeralPublicKey, 'spki')
24from cryptography.hazmat.primitives.serialization import load_der_public_key
25import base64
26...
27public_key = load_der_public_key(base64.b64decode(ephemeral_public_key))
28
Here, ephemeral_public_key
is the Base64 encoded X.509/SPKI DER key.
With this change of the Python code the shared secret can be determined.
Community Discussions contain sources that include Stack Exchange Network
Tutorials and Learning Resources in Cryptography
Tutorials and Learning Resources are not available at this moment for Cryptography