The easy way

The easiest way to get an extension ID is to generate the .pem file and extract the extension ID using the steps described in my other answer (read the part below the image).

The command-line way

The rest of this answer is for those who want to generate the extension ID with command-line tools only. I'm going to use OpenSSL because it is cross-platform.

First, we generate a private key. Keep this private key secret and do not lose it. Otherwise you will not be able to create a CRX file with the same extension ID. As of writing, the private keys generated by Chrome are 2048-bit RSA keys in PKCS #8 format (1024-bit until 2013). Throughout the answer, I will refer to this private key file as key.pem , because the Chrome Web Store expects that the private key is called key.pem .

Second, I show how to generate the value for the "key" field of the manifest file. This is just the public key, encoded in base64 format.

The third command in my answer shows how to calculate the extension ID given a public key (derived from a private key).

Linux / Mac

OpenSSL is installed on most Linux distros. If not, just install openssl via your favorite package manager.

# Create private key called key.pem 2>/dev/null openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -out key.pem # Generate string to be used as "key" in manifest.json (outputs to stdout) 2>/dev/null openssl rsa -in key.pem -pubout -outform DER | openssl base64 -A # Calculate extension ID (outputs to stdout) 2>/dev/null openssl rsa -in key.pem -pubout -outform DER | shasum -a 256 | head -c32 | tr 0-9a-f a-p

I've put 2>/dev/null at the start of each line to prevent "writing RSA key" from being output to the console.

Windows

If you don't have OpenSSL, you can get a precompiled binary from this mirror.

@echo off :: Assuming that you have installed OpenSSL in this directory SET PATH=%PATH%;C:\OpenSSL-Win32\bin :: Create private key called key.pem 2>NUL openssl genrsa -out priv.tmp 2048 2>NUL openssl pkcs8 -topk8 -in priv.tmp -nocrypt -out key.pem del priv.tmp :: Generate string to be used as "key" in manifest.json 2>NUL openssl rsa -in key.pem -pubout -outform DER -out pub.tmp 2>NUL openssl base64 -A -in pub.tmp del pub.tmp :: Calculate extension ID 2>NUL openssl rsa -in key.pem -pubout -outform DER -out pub.tmp 2>NUL openssl dgst -sha256 -out checksum.tmp pub.tmp SET /p EXTID=<checksum.tmp SET EXTID=%EXTID:* =% SET EXTID=%EXTID:~0,32% SET EXTID=%EXTID:f=p% SET EXTID=%EXTID:e=o% SET EXTID=%EXTID:d=n% SET EXTID=%EXTID:c=m% SET EXTID=%EXTID:b=l% SET EXTID=%EXTID:a=k% SET EXTID=%EXTID:9=j% SET EXTID=%EXTID:8=i% SET EXTID=%EXTID:7=h% SET EXTID=%EXTID:6=g% SET EXTID=%EXTID:5=f% SET EXTID=%EXTID:4=e% SET EXTID=%EXTID:3=d% SET EXTID=%EXTID:2=c% SET EXTID=%EXTID:1=b% SET EXTID=%EXTID:0=a% echo %EXTID% del checksum.tmp pub.tmp @echo on

I've put 2>NUL at the start of each line with the openssl command to hide a harmless warning about a missing config file.

Examples

Here is an example of running the previous commands on Linux. The relevant output of the commands are boldfaced. The first command creates a file, so there is no visible output in the shell. Note that the output of the second and third command do not end with a line break, so there is a "$" at the end of the line (which should not be copied).

$ # Create private key called key.pem $ 2>/dev/null openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -out key.pem $ # Generate string to be used as "key" in manifest.json (outputs to stdout) $ 2>/dev/null openssl rsa -in key.pem -pubout -outform DER | openssl base64 -A MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8vj7SK0NZ6ak7K6m6KEAkfGaNfKUahqFFms6W8rq+voaW7nETrpsMqNyhmBQ+ea0KkyI/S5XIrDQPqDcNpvesYlg9lsmi7CQBZjJw7zNqKkvn0oYaP4SNtWZfZopBumqFbzFi5cst2PT+XU9CBitxXNtocRtcjOsa44W1gPA5xanmtlF258N6Nann+rSOAdhIWqSo/J6fj72cxTNfmqLkwAvhdS4Zyux4F87vxp4YTSwElfYXFsHZWi7h66uuuMzqyOyJz5grhCJ24rtTshMQUCxQWyhO2XT2J1tVfUN1YVw6xdKUz3aGyKZeXCuql5klHmlqE9PTlbKj/1VMiIgCQIDAQAB$ $ # Calculate extension ID (outputs to stdout) $ 2>/dev/null openssl rsa -in key.pem -pubout -outform DER | sha256sum | head -c32 | tr 0-9a-f a-p mfabfdnimhipcapcioneheloaehhoggk$ $ cat key.pem # Show content of key.pem for completeness of this demo -----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDy+PtIrQ1npqTs rqbooQCR8Zo18pRqGoUWazpbyur6+hpbucROumwyo3KGYFD55rQqTIj9LlcisNA+ oNw2m96xiWD2WyaLsJAFmMnDvM2oqS+fShho/hI21Zl9mikG6aoVvMWLlyy3Y9P5 dT0IGK3Fc22hxG1yM6xrjhbWA8DnFqea2UXbnw3o1qef6tI4B2EhapKj8np+PvZz FM1+aouTAC+F1LhnK7HgXzu/GnhhNLASV9hcWwdlaLuHrq664zOrI7InPmCuEInb iu1OyExBQLFBbKE7ZdPYnW1V9Q3VhXDrF0pTPdobIpl5cK6qXmSUeaWoT09OVsqP /VUyIiAJAgMBAAECggEAIztFPKmTOwdn/MXqf+rwqTjuUopFSQllaPXNdYf8AL6J Wema9IuFquYWcjO/Ki1wzH1ik8vHaMlYuOwcYnLBnN69x5s6AKFukNEx2IclDyLR O/jDh13oCDl600KqVk1Fk3dW8cHPAxyfnRmJ6wWhFPOC3yUbdabWhpYI66mJrDhN ZpN04RmH7DIlhlBpvq/OMVodhRtqb4/EVJYghTxUsrsv/I+3t3zl/o/c0DiOjiVZ pEBYzn0rrHP8BAEhJWagGNgvotHPaVKAjoYcUiOUtMM4P1Js034XKjP4MHE1pMbN VlVnQMz3/6CXFL+wU1QqfohdChmcnc4QwM+vCFK47QKBgQD/FjHxhCJco0rNqNua B0inGx2Jfb4b+FWwLyNobaYey11o0MjpkpAvYcfe3zW8DQtmepDxGL8CpORoWtFg sVnmhAir0I6bxdZLMwKcp4T+kHW3n/ae3z8tPvMvclCnARGEp+ccyDH9X2iyaSd5 8DeJ6ND32+yr+vLgyyK/JW1z5wKBgQDz167cLe+xoRUqlKdJq8lzmij30lGVUT2D 5Fn+2YUKIMeVEM7PlEmu9UmpN5HMA+LSNeiMZ1uhW5YQovXlXZCWoRqieeI4LMoM M335hsAWpS8pFRdlXMy885w5FUC5v4Ji0RUI37WON6fxNd8zFVqAMOcAANg716RI MWfblCJOjwKBgQDV8BKBIbYEBfv10poja9p2NFqodqpcIQIU2uQScGvzxdIY14q5 wu9kndiYxpH1nuch0sf/PSbuG8do8kpKk1P37mKrXyZL5TgeJ7EYG7OCITxpfiLE Ci6dTv98mp6kAlRj8sH1tL2gaEWR5Hl0XpDl/DpOtsefUcAj4prIv6Y1nwKBgGUk obNSmonjdxQidQFp8DWzTCr/Yje9ava6UVoUf8qjriV2w1H3AFlCBTvbgO5O7laj ZcJXXPqhMq3T6ospNEBGsvWR+PO0IFrPQQGvkx3Rhq5TwVCaHZKCudozppVlin/S mhcENBq5mz/CSMK3qMJjhm3J6+dmmw4W8C10VIahAoGARf4zus0TQIxRlix1Oaaz sM5yANLcLivoeJDVOlUFUWgeSUc6Yma8T/FYlAkEVyyK+/nCWNErTS2yOzXEff01 n8F0h1DJ4K5zxt0OhGUIUAGgR/kqpub0omqTJcJndLv2qgzofwK21Uih6yQzDeus lJsf3m3tuax5kcmhnDojbtE= -----END PRIVATE KEY-----