I have a Chrome extension I made, but based it on some example found online. Its not in a crx file. The extension ID is the one used in the example. I would like to change it before I upload my extension to the chrome store. My question is how do I change this? Do I just manually change the letters in my manifest.json file? Or does the extension id have to be generated from something because its in a fixed format? Same for the key, can I just randomly change these two before I do anything else now that I'm ready?
{
// Extension ID: rnldjzfmornpzlahmmmgbagdohdnhdic
"key": "MIGfMA3GCSqGSIb3DFEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaZhSpDCE9RCocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB",
"name": "Name of extension",
...
Note that extension signing consists of two "keys":
The private key file, .pem, that is used to sign CRX files and must remain the same for future updates.
The resulting public key in the manifest - can't be used to sign future updates (used to verify the signature instead), but can be used to force a particular ID for unpacked extensions since the ID is derived as a hash of the public key. (For those curious, if key is not present an unpacked extension falls back to hashing the path).
You have 2 options:
Let Google handle it.
Remove the key field from the manifest completely; then submit it to the store.
CWS will generate a new keypair for your extension (and, consequently, a new ID), which will be preserved between updates. If you need to maintain the ID for your development version (not always a good idea, as Chrome will get confused with autoupdates, but a good idea during storage.sync testing), you can extract the new public key from your Developer Dashboard using "More info" link on your item.
However, there is no way to get the .pem key from CWS. You are forever locked in CWS as auto-update source. That shouldn't matter though as Chrome disallows extension installs from elsewhere.
Retain control of the private key.
Note: this apporoach may be deprecated by now, and there's not much practical reason to use it.
You can generate a CRX file of your extension from chrome://extensions using "Pack extension" function.
If you don't provide an existing .pem file, Chrome will generate a new keypair (and thus, ID) for your extension.
Guard the resulting .pem key with your life carefully. It can be used to impersonate you as a developer when it comes to updates.
Then, when you submit the extension to CWS, include the .pem in the archive's root as key.pem (Note: removed from documentation; links to an archived version). This instructs CWS to use it instead of generating a new keypair. Note that you have to provide your private key to Google, since it modifies the extensions before signing.
Since the ID is a hash of a (randomly-generated) public key, there is a tiny chance of collision with an existing extension. If that happens, just re-generate the .pem file for a different one.
In either case: do not include the key field in the manifest when uploading, or CWS may reject it.
Also, do not hardcode the extension ID in your extension anywhere. It's accessible using one of those functions:
chrome.runtime.getManifest().id // gives "youridehere"
chrome.runtime.getURL("something") // gives "chrome-extension://youridhere/something"
And in CSS files, you can use __MSG_##extension_id__ as a macro:
background-image:url('chrome-extension://__MSG_##extension_id__/background.png');
You can create you own key and extension ID for the manifest:
openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -out key.pem
Key:
openssl rsa -in key.pem -pubout -outform DER | openssl base64 -A
Extension ID:
openssl rsa -in key.pem -pubout -outform DER | shasum -a 256 | head
-c32 | tr 0-9a-f a-p
Related
I have a problem when I am making a request with Axios in node getting Error: ca md too weak.
I am sending .pfx file and password for the pfx certificate file.
I can easily access API using Postman and sending pfx certificate and password, but making a request with Axios in node js (v. 18.0) I get Error: ca md too weak.
I don't want to downgrade Node version and using: process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; also doesn't help.
Also to connect to the server I have to use VPN and this error pops up even if I haven't turned on VPN.
Is it possible to bypass this check, so I can send a request as I do in the Postman?
Here is a code example:
agent = new https.Agent({
pfx: fs.readFileSync((process.cwd() + "\\src\\sources\\KIISWSClient.pfx")),
passphrase: 'password',
rejectUnauthorized: false,
});
userKiisData = axios.post('https://ws-kiis.hlk.hr/AdeoMembersPublicService.svc/WSPublic/BasicData', {
Username: "myusername",
Role: "role"
}, {
auth: {
username: "user",
password: "mypassword"
},
httpsAgent: agent
}
return userKiisData
Here is the error:
Error: ca md too weak
at configSecureContext (node:internal/tls/secure-context:278:15)
at Object.createSecureContext (node:_tls_common:113:3)
at Object.connect (node:_tls_wrap:1622:48)
at Agent.createConnection (node:https:142:22)
at Agent.createSocket (node:_http_agent:343:26)
at Agent.addRequest (node:_http_agent:294:10)
at new ClientRequest (node:_http_client:311:16)
at Object.request (node:https:352:10)
TLDR: jump to end if you don't care about understanding
rejectUnauthorized directs nodejs to accept (some) invalid certs used by the server instead of aborting the connection, but this error is occurring on your own client cert/chain not that of the server. (That's why it can occur even without the VPN you need for an actual connection.) The "CA_MD_TOO_WEAK" check occurs in modern versions of OpenSSL (1.1.0 up) but can vary depending on how the OpenSSL was built, thus for nodejs it also depends whether your nodejs was built to use its own embedded OpenSSL (usual on Windows) or one already provided on the system where it is installed (usual on Linux).
You can look at the signature algorithms(s) used in your cert chain with openssl if you have (or get) it on this machine or you (may, can, and do) copy the pfx to a machine where ditto. First do
openssl pkcs12 -in yourpfxfile -nokeys >temp0
and look at temp0; it should contain one or more blocks each consisting of a subject= line, an issuer= line, a -----BEGIN CERTIFICATE----- line, several lines of base64, and an -----END CERTIFICATE----- line. (Likely there are also Bag Attributes: lines optionally followed by indented lines; ignore those.)
If there is only one block and it has the same value for subject and issuer, then your error should not have happened, because the cert is selfsigned and OpenSSL should not be checking signature strength on selfsigned cert. Otherwise, do
openssl x509 -in temp0 -noout -text -certopt no_pubkey,no_sigdump,no_extensions
and you should get a few lines of output that includes signatureAlgorithm: x where x is of the form {hash}withRSAEncryption ecdsa_with_{hash} dsa-with-{hash} or dsaWith{hash}. If {hash} is MD5, the signature on your certificate is weak and doesn't provide the security it claims -- although in your situation, if the server accepts it in spite of this weakness, it's probably not your problem.
If the first (leaf) cert is not selfsigned (subject not same as issuer) and its signature algorithm does not use MD5, either
the OpenSSL used by your nodejs is set to a higher than usual 'security level' -- this is not likely for a nodejs that has embedded OpenSSL but more plausible for a system-provided one, especially on security-focussed systems like RedHat 8; or
the problem is with a cert other than the first one (i.e. a CA cert), but this shouldn't occur if your cert(s) are from a properly-run CA because such a CA should never have a higher CA cert signed with a weaker key or signature algorithm than the leaf cert, except the selfsigned root whose signature doesn't matter, and isn't checked so it wouldn't cause your error. However, if you want, break each block other than the first into a separate file, and repeat the openssl x509 procedure above on each except if the last one has subject and issuer the same don't check it because it is the selfsigned root cert.
Anyway, workaround: add to your https-Agent options ciphers: "DEFAULT:#SECLEVEL=0". This should turn off several checks designed to prevent insecure SSL/TLS connections, including the one relevant here; as a result, if you use this code to process data of any importance, it may be at higher risk depending on what the server does.
I found spkac from this document:
https://nodejs.org/api/crypto.html#crypto_certificate_exportchallenge_spkac
const spkac = getSpkacSomehow();
The docs says getSpkacSomehow.
How can I get spkac? What's the detail?
SPKAC represents Netscape signed public key and challenge.
As stated in the doc, in this scenario, the SPKAC should come from an HTML form's <keygen> element.
Though you can also use openssl to generate a SPKAC manually: openssl spkac -key key.pem -challenge hello -out spkac.cnf, see openssl doc
Anyway, since the <keygen> element has been deprecated, this should not be used anymore.
If you're interested, here's a little history about SPKAC.
I am trying to validate calls to my API from an IOS app. I have generated keys for backend like so:
openssl genrsa -aes256\
-passout pass:pass\
-out signature_private_key.pem 2048
openssl rsa \
-in signature_private_key.pem\
-passin pass:pass\
-out signature_public_key.pem\
-outform PEM\
-pubout
In the node backend I am validating the call like this:
static createSignatureString(bodyString, apiKey, timestamp) {
const bodyHash = crypto
.createHash("sha256")
.update(bodyString)
.digest("base64");
return `${bodyHash}:${apiKey}:${timestamp}`;
}
static createSignature(string, privateKey) {
const sign = crypto.createSign("RSA-SHA256");
sign.write(string);
sign.end();
return sign.sign(privateKey, "base64");
}
static verifySignature(xMessageSignatureString, signature, publicKey) {
const verify = crypto.createVerify("RSA-SHA256");
verify.update(xMessageSignatureString);
verify.end();
return verify.verify(publicKey, new Buffer(signature, "base64"));
}
The mobile app uses a .p12 file to generate a signature and send to the rest API. Given the above how would I generate a .p12 file using openssl that would send a valid signature?
To create a PKCS12 file you need the private key (which you have) and an (X.509) certificate containing the matching publickey, or if applicable a series of certificates starting with the matching one called a 'chain'. Either you can get this certificate/chain from a CA, or OpenSSL can create a self-signed certificate which uses no chain and which is acceptable to many applications but not all:
openssl req -new -x509 -key privatekeyfile -out certfile [-days N] [-$hash]
-days N specifies how long you want the cert to be valid; for dummy certs it is common to choose a large value like 3650 for about 10 years, or more, although you can as easily generate a replacement in the future if you need to. It's safest not to go beyond 2037 because some C programs, though fewer than in the past, are still affected by the Y2038 bug. You can specify the hash used in the self-signature; this doesn't really matter, but some people prefer to avoid the default (SHA1) and use e.g. -sha256 instead. You can specify the 'subject' name on the commandline if you wish with -subj; see the man page. There are also many extensions which can be placed in an X.509 certificate, but whether you want any of them and if so which ones and what values varies depending on the application(s) that will use it.
Once you have the cert and privatekey in files:
openssl pkcs12 -export -in certfile -inkey privatekeyfile -out p12file
On both of these commands you can specify passwords on the commandline, as you did in the commands you posted, if you prefer; see the man pages and/or usage messages. Remember that this practice makes your passwords temporarily visible to other processes, often including other users if on a shared system.
For clarity: on CA-issued certs the signature hash does matter and should not be SHA1 or weaker, but on root or self-signed certs it normally does not matter.
I'm trying to get client certificate verification working with ColdFusion10 http requests. Currently, all I'm getting back is a 403.7. I believe ColdFusion isn't picking up my client certificate. Below is the steps I've currently taken to install and get it set up.
What I've done:
Created a self-signed SSL certificate and installed it to my default website on IIS 7.5.
Installed the SSL cert into CF store.
Tested HTTPS request, everything works fine.
Followed this guide for CA and Client Certs. https://ondrej.wordpress.com/2010/01/24/iis-7-and-client-certificates/
Installed the CA cert to server and client (through MMC). Installed client cert (.pfx) on client.
Tested in local browser, everything is working as it should up to this point.
Created another client cert for CF10 (.cer, .pvk, .pfx).
Added the CA cert into CF store.
Tested, HTTPS rejected with 403.7.
Added CA cert, client .pfx and .cer through MMC under CF10.
Tested, rejected again with 403.7 still.
I've seen that there has been issues with CFHTTP and client certs before, but I haven't found an solution yet.
If anyone can help me with this, it would be great.
EDIT:
After doing what Miguel-F suggested, I skimmed through the log files and found that my CA was imported inside the ColdFusion trust store, but my client certificate wasn't there. I assume this is the reason for the 403.7.
However, I can't add my client certificate(.pfx) to the trust store using certman or keytool through cmd. I created the .pfx by merging my .cer and .pvk together, so I have both of those also.
How can I add my .pfx to the trust store so that Coldfusion picks it up and validates my https?
EDIT #2:
After following this to add my .pfx to the keystore, I can now see my client cert along with my CA being added as 'trusted cert' during the https request.
However, I'm still getting the 403.7 - Forbidden error.
Edit #3:
The handshake in ssl debug info after adding my .pfx (see edit #2) is:
'Is initial handshake: true'
'catalina-exec-3, WRITE: TLSv1 Handshake, length = 181' (Several of these in 1 request)
Edit #4 (More Debug Info):
The last section above where it returns 403 in the debug info looks like HTML content for the error page returned by the server. Just above that however is this:
catalina-exec-3, READ: TLSv1 Application Data, length = 5808
Padded plaintext after DECRYPTION: len = 5808
0000: 48 54 54 50 2F 31 2E 31 20 34 30 33 20 46 6F 72 HTTP/1.1 403 For (Example of the HTML error content)
Edit #5:
I can see my client cert being added as a trusted cert during the start of the request... It's just not using it.
adding as trusted cert:
Subject: CN=George CF10
Issuer: CN=MyPersonalCA
Algorithm: RSA; Serial number: 0x-431b7d9911f9856cb0adf94d50bb1479
Valid from Fri Apr 01 00:00:00 BST 2016 until Wed Apr 01 00:00:00 BST 2020
Edit #6:
After adding setClientCert(path to my .pfx) and setClientCertPassword(client cert password) to my https request, I'm seeing this error:
Error while trying to get the SSL client certificate:
java.security.UnrecoverableKeyException: Could not decrypt key: Could not decode key from BER. (Invalid encoding: expected tag not there.).
Check that the certificate path and password are correct and the file is in PKCS#12 format.
Too long for comment
Are you sure that you added the certificate to the correct JVM keystore? If you have upgraded Java on your ColdFusion server then it may not be in the default location. The ColdFusion administrator system information page will tell you the path in use under the "Java Home" label.
In order to turn on debugging information, add these lines to your ColdFusion server's jvm.config file located under this directory C:\ColdFusion10\cfusion\bin (by default) and restart the ColdFusion service:
-Djavax.net.ssl=debug
-Djavax.net.debug=all
This should add some more information to the coldfusion-out.log log file on your server. Post that information back here into your question for further analysis.
Adding the certificate to the Windows server using MMC is not needed and does not help your cfhttp calls from ColdFusion. It uses the Java keystore.
Response for EDIT 1 and 2
Follow the steps from this other answer on how to convert a .pfx file to the keystore.
Response for EDIT 3, 4 and 5
If you still have the ssl debug switch turned on you should see the handshake info in the log file. What does it show now that you have the certificate installed?
Have you tried using the clientCert and clientCertPassword attributes of the cfhttp tag? Note that it will require the full path to a PKCS12 format file that contains the client certificate for the request. See the docs here.
Response for EDIT 6
Take a look at this page - CFHTTP and client certificates regarding the error message you are getting: Could not decode key from BER. Excerpt from that page:
The client certificate appeared to be a normal client certificate with private key in PKCS#12 format, but from a different certificate chain then the server format. So I first had the client double-check that the chain was correctly installed on the server. Unfortunately it wasn’t that easy. I will spare you the details of what I tried, but in the end it turned out to be that the certificate was incorrectly encoded. These are the actual conversion steps I took to convert the certificate to a working state:
import the certificate in the Windows Certificate store through the MMC;
export the certificate with private key, whole chain and without strong encryption in PFX formet;
convert the PFX encoded certificate to PEM using OpenSSL:openssl pkcs12 -in raw.pfx -out intermediate.pem -nodes
re-order the certificates inside the PEM file to the following order: > - Identity certificate
Intermediate certificate
Root certificate
Private Key
convert the PEM encoded certificate to PKCS#12 using OpenSSL:openssl pkcs12 -export -out final.pkcs -in final.pem
It is probably possible to skip / merge a few of these steps (you probably just need to convert to PEM, reorder and convert back), but I really didn’t have time to explore that, I just know that this worked for me.
Solved by following this link.
I used the new .pkcs format file inside setClientCert of the HTTP request and it is now working.
import the certificate in the Windows Certificate store through the MMC;
export the certificate with private key, whole chain and without strong encryption in PFX formet;
convert the PFX encoded certificate to PEM using OpenSSL:
openssl pkcs12 -in raw.pfx -out intermediate.pem -nodes
re-order the certificates inside the PEM file to the following order:
Identity certificate
Intermediate certificate
Root certificate
Private Key
convert the PEM encoded certificate to PKCS#12 using OpenSSL: openssl pkcs12 -export -out final.pkcs -in final.pem
It is probably possible to skip / merge a few of these steps (you probably just need to convert to PEM, reorder and convert back), but I really didn’t have time to explore that, I just know that this worked for me.
I need to connect client & server over untrusted network. I've considered using TLS (crypto/tls), but from what I understand, I first need to create a create a crypto/x509.Certificate. But I feel overwhelmed by all the parameters I need to pass to the x509.CreateCertificate() function - it says it needs all of the following fields:
SerialNumber, Subject, NotBefore, NotAfter, KeyUsage, BasicConstraintsValid, IsCA, MaxPathLen, SubjectKeyId, DNSNames, PermittedDNSDomainsCritical, PermittedDNSDomains.
I have full control over both endpoints, so I believe I don't need any expiration or invalidation support/parameters (I can change keys both on client and server at any time I want) - so I can probably skip NotBefore and NotAfter (? or do I have to set them anyway?). What should I put in all the other fields, and why, to avoid any vulnerabilities? Also, can I use the same private/public key pair for both ways authentication (client to server, and server to client), or do I have to use 2 pairs?
Or, is there something simpler than TLS that I could use? Note however, that I need to two way authentication.
EDIT:
I created a simple library based on suggestions from the accepted answer, plus key generation code from generate_cert.go - see:
github.com/akavel/tunnel
Owlstead is partly correct. Your best bet is creating self signed certificates using OpenSSL. However, I would then use the Go TLS library for encryption. Below is some code that may help you.
Creating an x509 key pair
I normally follow the instructions here. Summary of commands (do for both client and server):
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Using Go's TLS library
First, create a tls.Config. One TLS config will work on both client and server but some of the options only need to be set on one or the other:
cert, err := tls.LoadX509KeyPair(cert, key)
config := &tls.Config{
Certificates: []Certificates{cert},
ClientAuth: tls.RequireAnyClientCert, // Must be done on server
InsecureSkipVerify: true, // Must be done on client
}
On the server, you need to setup a TLS listener. This sets it up on port 4443:
listener, err := tls.Listen("tcp", ":4443", config)
for {
conn, err := listener.Accept()
acceptConn(conn) // your code
}
On the client:
conn, err := tls.Dial("tcp", serverAddr, config)
This will create an encrypted connection, but it will not verify the other side is who they say they are. The easiest way to do that is to give each server the public key of the other server and compare it to the server that has just connected. To find the public key on the other server, you need to:
c := conn.(*tls.Conn) // convert net.Conn from listener to tls conn
err := c.Handshake() // ensure handshake is completed without error
state := c.ConnectionState()
pubKey, err := x509.MarshalPKIXPublicKey(state.PeerCertificates[0])
bytes.Equal(pubKey, knownKey) // compare to known value
As owlstead stated, TLS is still your best bet. Creating your own certificates can be done by following some online guide.
The following article lets you create your own SSL root certificate (You effectively become your own Root CA, like Verisign and such). With this, you can create and sign your own application certificates and distribute them. If, as you say, you have full control over both end points, this is probably worth checking in to.
http://www.eclectica.ca/howto/ssl-cert-howto.php/