如何为本地主机创建自签名证书?

发布于 2024-12-17 01:10:17 字数 298 浏览 2 评论 0原文

我已完成 如何使用 https / SSL 中详细说明的步骤在本地主机上? 但这会为我的计算机名称设置一个自签名证书,并且当通过 https://localhost 我收到 IE 警告。

有没有办法为“localhost”创建自签名证书来避免此警告?

I've gone through the steps detailed in How do you use https / SSL on localhost? but this sets up a self-signed cert for my machine name, and when browsing it via https://localhost I receive the IE warning.

Is there a way to create a self-signed cert for "localhost" to avoid this warning?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

半岛未凉 2024-12-24 01:10:17

由于这个问题被标记为IIS,并且我找不到关于如何获得受信任证书的好答案,因此我将给出我的2美分:

首先以管理员身份在PowerShell中使用来自@AuriRahimzadeh的命令:

New-SelfSignedCertificate -DnsName "localhost" -CertStoreLocation "cert:\LocalMachine\My" -NotAfter (Get-Date).AddYears(100)

添加了 100 年有效期,以便本地主机的证书不会过期。如果您希望使用 -NotAfter (Get-Date).AddMonths(24) 或任何其他值来代替 24 个月,则可以使用该值。

这很好,但证书不受信任,会导致以下错误。这是因为它没有安装在受信任的根证书颁发机构中。

输入图片描述这里

通过启动 mmc.exe 来解决此问题。

然后转到:

文件->添加或删除管理单元 ->证书->添加->电脑账户->本地计算机。单击“完成”。

展开 Personal 文件夹,您将看到您的 localhost 证书:

在此处输入图像描述

将证书复制到受信任的根证书颁发机构 - 证书文件夹。

最后一步是打开 Internet 信息服务 (IIS) 管理器 或简单地打开 inetmgr.exe。从那里转到您的站点,选择绑定...添加...编辑...。设置 https 并从下拉列表中选择您的证书。

输入图像描述这里

您的证书现已受信任:

在此处输入图像描述

Since this question is tagged with IIS and I can't find a good answer on how to get a trusted certificate I will give my 2 cents about it:

First use the command from @AuriRahimzadeh in PowerShell as administrator:

New-SelfSignedCertificate -DnsName "localhost" -CertStoreLocation "cert:\LocalMachine\My" -NotAfter (Get-Date).AddYears(100)

Added Valid to 100 years so that the cert for localhost hopefully does not expire. You can use -NotAfter (Get-Date).AddMonths(24) for 24 months if you want that instead or any other value.

This is good but the certificate is not trusted and will result in the following error. It is because it is not installed in Trusted Root Certification Authorities.

enter image description here

Solve this by starting mmc.exe.

Then go to:

File -> Add or Remove Snap-ins -> Certificates -> Add -> Computer account -> Local computer. Click Finish.

Expand the Personal folder and you will see your localhost certificate:

enter image description here

Copy the certificate into Trusted Root Certification Authorities - Certificates folder.

The final step is to open Internet Information Services (IIS) Manager or simply inetmgr.exe. From there go to your site, select Bindings... and Add... or Edit.... Set https and select your certificate from the drop down.

enter image description here

Your certificate is now trusted:

enter image description here

高跟鞋的旋律 2024-12-24 01:10:17

虽然这篇文章被标记为适用于 Windows,但它是 OS X 上的相关问题,我在其他地方还没有看到答案。以下是在 OS X 上为 localhost 创建自签名证书的步骤:

# Use 'localhost' for the 'Common name'
openssl req -x509 -sha256 -nodes -newkey rsa:2048 -days 365 -keyout localhost.key -out localhost.crt

# Add the cert to your keychain
open localhost.crt

Keychain Access 中,双击这个新的 localhost 证书。展开“信任”旁边的箭头并选择“始终信任”。 Chrome 和 Safari 现在应该信任此证书。例如,如果您想将此证书与 node.js 一起使用:

var options = {
    key: fs.readFileSync('/path/to/localhost.key').toString(),
    cert: fs.readFileSync('/path/to/localhost.crt').toString(),
    ciphers: 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384',
    honorCipherOrder: true,
    secureProtocol: 'TLSv1_2_method'
};

var server = require('https').createServer(options, app);

Although this post is post is tagged for Windows, it is relevant question on OS X that I have not seen answers for elsewhere. Here are steps to create a self-signed cert for localhost on OS X:

# Use 'localhost' for the 'Common name'
openssl req -x509 -sha256 -nodes -newkey rsa:2048 -days 365 -keyout localhost.key -out localhost.crt

# Add the cert to your keychain
open localhost.crt

In Keychain Access, double-click on this new localhost cert. Expand the arrow next to "Trust" and choose to "Always trust". Chrome and Safari should now trust this cert. For example, if you want to use this cert with node.js:

var options = {
    key: fs.readFileSync('/path/to/localhost.key').toString(),
    cert: fs.readFileSync('/path/to/localhost.crt').toString(),
    ciphers: 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384',
    honorCipherOrder: true,
    secureProtocol: 'TLSv1_2_method'
};

var server = require('https').createServer(options, app);
ペ泪落弦音 2024-12-24 01:10:17

您可以使用 PowerShell 通过 new-selfsignedcertificate cmdlet 生成自签名证书:

New-SelfSignedCertificate -DnsName "localhost" -CertStoreLocation "cert:\LocalMachine\My"

注意:makecert.exe 已弃用。

Cmdlet 参考:
https://learn.microsoft。 com/en-us/powershell/module/pki/new-selfsignedcertificate?view=windowsserver2022-ps

You can use PowerShell to generate a self-signed certificate with the new-selfsignedcertificate cmdlet:

New-SelfSignedCertificate -DnsName "localhost" -CertStoreLocation "cert:\LocalMachine\My"

Note: makecert.exe is deprecated.

Cmdlet Reference:
https://learn.microsoft.com/en-us/powershell/module/pki/new-selfsignedcertificate?view=windowsserver2022-ps

晒暮凉 2024-12-24 01:10:17

在这个问题上花费了大量时间后,我发现每当我按照使用 IIS 制作自签名证书的建议时,我发现颁发给和颁发者不正确。 SelfSSL.exe是解决这个问题的关键。以下网站不仅提供了制作自签名证书的分步方法,还解决了颁发给和颁发者问题。 这里是我发现的制作自签名证书的最佳解决方案。如果您希望以视频形式观看相同的教程 点击此处

SelfSSL 的使用示例如下所示:

SelfSSL /N:CN=YourWebsite.com /V:1000 /S:2

SelfSSL /? 将提供一个列表参数及解释。

After spending a good amount of time on this issue I found whenever I followed suggestions of using IIS to make a self signed certificate, I found that the Issued To and Issued by was not correct. SelfSSL.exe was the key to solving this problem. The following website not only provided a step by step approach to making self signed certificates, but also solved the Issued To and Issued by problem. Here is the best solution I found for making self signed certificates. If you'd prefer to see the same tutorial in video form click here.

A sample use of SelfSSL would look something like the following:

SelfSSL /N:CN=YourWebsite.com /V:1000 /S:2

SelfSSL /? will provide a list of parameters with explanation.

栀子花开つ 2024-12-24 01:10:17

如果您正在尝试创建一个自签名证书,可以让您访问http://localhost/mysite
然后这是一种创建它的方法

makecert -r -n "CN=localhost" -b 01/01/2000 -e 01/01/2099 -eku 1.3.6.1.5.5.7.3.1 -sv localhost.pvk localhost.cer
cert2spc localhost.cer localhost.spc
pvk2pfx -pvk localhost.pvk -spc localhost.spc -pfx localhost.pfx

http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/32bc5a61-1f7b-4545-a514-a11652f11200

If you are trying to create a self signed certificate that lets you go http://localhost/mysite
Then here is a way to create it

makecert -r -n "CN=localhost" -b 01/01/2000 -e 01/01/2099 -eku 1.3.6.1.5.5.7.3.1 -sv localhost.pvk localhost.cer
cert2spc localhost.cer localhost.spc
pvk2pfx -pvk localhost.pvk -spc localhost.spc -pfx localhost.pfx

From http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/32bc5a61-1f7b-4545-a514-a11652f11200

ζ澈沫 2024-12-24 01:10:17

我会推荐 Pluralsight 用于创建自签名证书的工具:

将您的证书制作为 .pfx 并将其导入 IIS。并将其添加为受信任的根证书颁发机构。

I would recomment Pluralsight's tool for creating self-signed-certs: http://blog.pluralsight.com/selfcert-create-a-self-signed-certificate-interactively-gui-or-programmatically-in-net

Make your cert as a .pfx and import it into IIS. And add it as a trusted root cert authority.

枕花眠 2024-12-24 01:10:17

生成本地主机证书的最快方法。

openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")

Fastest Way to generate localhost certificate.

openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
谜兔 2024-12-24 01:10:17

是和不是。自签名证书会导致该警告消息,因为该证书不是由受信任的证书颁发机构签名的。您可以考虑使用一些选项来删除本地计算机上的此警告。有关详细信息,请参阅此问题排名最高的答案:

我需要做什么才能让 Internet Explorer 8 接受自签名证书?

希望这会有所帮助!


编辑:

抱歉,我最初并不知道您被限制在本地主机上。您可以尝试按照以下链接中的说明“生成具有正确公用名的自签名证书”。

http:// www.sslshopper.com/article-how-to-create-a-self-signed-certificate-in-iis-7.html

Yes and no. Self signed certificates result in that warning message because the certificate was not signed by a trusted Certificate Authority. There are a few options that you can consider to remove this warning on your local machine. See the highest ranked answers to this question for details:

What do I need to do to get Internet Explorer 8 to accept a self signed certificate?

Hope this helps!


EDIT:

Sorry, I wasn't initially aware that you were constrained to localhost. You can attempt to follow the directions on the the link below to "Generate a Self Signed Certificate with the Correct Common Name."

http://www.sslshopper.com/article-how-to-create-a-self-signed-certificate-in-iis-7.html

澉约 2024-12-24 01:10:17

在 LAN(局域网)中,我们有一台服务器计算机,此处名为 xhost,运行 Windows 10,IIS 被激活为 WebServer。我们必须通过 Google Chrome 之类的浏览器访问这台计算机,不仅可以从服务器本身通过 https://localhost/ 从 localhost 访问,还可以从 LAN 中的其他主机使用 URL https://xhost 访问此计算机/ :


https://localhost/
https://xhost/
https://xhost.local/
...

采用这种访问方式,我们没有完全限定的域名,这里只有本地计算机名称xhost。

或者从 WAN:


https://dev.example.org/
...

您应该将 xhost 替换为您真实的本地计算机名称。

上述解决方案都不能令我们满意。经过几天的尝试,我们采用了openssl.exe的解决方案。我们使用 2 个证书 - 由前者认证的 CA(自我认证机构证书)RootCA.crt 和 xhost.crt。我们使用 PowerShell。

1. 创建并更改为安全目录:

cd C:\users\so\crt

2. 生成 RootCA.pem、RootCA.key &RootCA.crt 作为自我认证的证书颁发机构:


openssl req -x509 -nodes -new -sha256 -days 10240 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=ZA/CN=RootCA-CA"
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt

3. 提出认证请求:xhost.key、xhost .csr:

C: Country
ST: State
L: locality (city)
O: Organization Name
Organization Unit
CN: Common Name

    

openssl req -new -nodes -newkey rsa:2048 -keyout xhost.key -out xhost.csr -subj "/C=ZA/ST=FREE STATE/L=Golden Gate Highlands National Park/O=WWF4ME/OU=xhost.home/CN=xhost.local"

4.获得RootCA.pem认证的xhost.crt:


openssl x509 -req -sha256 -days 1024 -in xhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out xhost.crt

使用extfiledomains.ext文件定义许多安全的访问方式服务器网站:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = xhost
DNS.3 = xhost.local
DNS.4 = dev.example.org
DNS.5 = 192.168.1.2

5. 制作 xhost.pfx PKCS #12,

结合私有 xhost.key 和证书 xhost.crt,允许导入到 iis 中。此步骤要求输入密码,请按[RETURN]键将其清空(无需密码):


openssl pkcs12 -export -out xhost.pfx -inkey xhost.key -in xhost.crt

iis10 中导入 xhost.pfx

6.在 xhost 计算机(此处为 localhost)中安装的 。并重新启动 IIS 服务。

IIS10 Gestionnaire des services Internet (IIS) (%windir%\system32\inetsrv\InetMgr.exe)

输入图片此处描述

在此处输入图片描述

7. 在端口 443 上将 ssl 与 xhost.local 证书绑定。

在此处输入图像描述

重新启动 IIS 服务。

将 RootCA.crt 导入到受信任的根证书颁发机构

8.在任何将访问网站 https://xhost/ 的计算机上,通过 Google Chrome

。 \谷歌浏览器/…/设置
/[高级]/隐私与安全/安全/管理证书

导入 RootCA.crt

在此处输入图像描述

浏览器将显示此有效的证书树:


RootCA-CA
  |_____ xhost.local

在此处输入图像描述

通过 LAN,即使通过 WAN,也不会出现证书错误 https://dev.example.org< /a>.

输入图片此处描述

这是整个 Powershell 脚本 socrt.ps1 文件,用于从零开始生成所有必需的证书文件:


#
# Generate:
#   RootCA.pem, RootCA.key RootCA.crt
#
#   xhost.key xhost.csr xhost.crt
#   xhost.pfx
#
# created  15-EEC-2020
# modified 15-DEC-2020
#
#
# change to a safe directory:
#

cd C:\users\so\crt

#
# Generate RootCA.pem, RootCA.key & RootCA.crt as Certification Authority:
#
openssl req -x509 -nodes -new -sha256 -days 10240 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=ZA/CN=RootCA-CA"
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt

#
# get RootCA.pfx: permitting to import into iis10: not required.
#
#openssl pkcs12 -export -out RootCA.pfx -inkey RootCA.key -in RootCA.crt

#
# get xhost.key xhost.csr:
#   C: Country
#   ST: State
#   L: locality (city)
#   O: Organization Name
#   OU: Organization Unit
#   CN: Common Name
#
openssl req -new -nodes -newkey rsa:2048 -keyout xhost.key -out xhost.csr -subj "/C=ZA/ST=FREE STATE/L=Golden Gate Highlands National Park/O=WWF4ME/OU=xhost.home/CN=xhost.local"

#
# get xhost.crt certified by RootCA.pem:
# to show content:
#   openssl x509 -in xhost.crt -noout -text
#
openssl x509 -req -sha256 -days 1024 -in xhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out xhost.crt

#
# get xhost.pfx, permitting to import into iis:
#
openssl pkcs12 -export -out xhost.pfx -inkey xhost.key -in xhost.crt

#
# import xhost.pfx in iis10 installed in xhost computer (here localhost).
#

要安装适用于 Windows 的 openSSL,请访问 https://slproweb.com/products/Win32OpenSSL.html

In a LAN (Local Area Network) we have a server computer, here named xhost running Windows 10, IIS is activated as WebServer. We must access this computer via Browser like Google Chrome not only from localhost through https://localhost/ from server itsself, but also from other hosts in the LAN with URL https://xhost/ :


https://localhost/
https://xhost/
https://xhost.local/
...

With this manner of accessing, we have not a fully-qualified domain name, but only local computer name xhost here.

Or from WAN:


https://dev.example.org/
...

You shall replace xhost by your real local computer name.

None of above solutions may satisfy us. After days of try, we have adopted the solution openssl.exe. We use 2 certificates - a CA (self certified Authority certificate) RootCA.crt and xhost.crt certified by the former. We use PowerShell.

1. Create and change to a safe directory:

cd C:\users\so\crt

2. Generate RootCA.pem, RootCA.key & RootCA.crt as self-certified Certification Authority:


openssl req -x509 -nodes -new -sha256 -days 10240 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=ZA/CN=RootCA-CA"
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt

3. make request for certification: xhost.key, xhost.csr:

C: Country
ST: State
L: locality (city)
O: Organization Name
Organization Unit
CN: Common Name

    

openssl req -new -nodes -newkey rsa:2048 -keyout xhost.key -out xhost.csr -subj "/C=ZA/ST=FREE STATE/L=Golden Gate Highlands National Park/O=WWF4ME/OU=xhost.home/CN=xhost.local"

4. get xhost.crt certified by RootCA.pem:


openssl x509 -req -sha256 -days 1024 -in xhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out xhost.crt

with extfile domains.ext file defining many secured ways of accessing the server website:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = xhost
DNS.3 = xhost.local
DNS.4 = dev.example.org
DNS.5 = 192.168.1.2

5. Make xhost.pfx PKCS #12,

combinig both private xhost.key and certificate xhost.crt, permitting to import into iis. This step asks for password, please let it empty by pressing [RETURN] key (without password):


openssl pkcs12 -export -out xhost.pfx -inkey xhost.key -in xhost.crt

6. import xhost.pfx in iis10

installed in xhost computer (here localhost). and Restart IIS service.

IIS10 Gestionnaire des services Internet (IIS) (%windir%\system32\inetsrv\InetMgr.exe)

enter image description here

enter image description here

7. Bind ssl with xhost.local certificate on port 443.

enter image description here

Restart IIS Service.

8. Import RootCA.crt into Trusted Root Certification Authorities

via Google Chrome in any computer that will access the website https://xhost/.

\Google Chrome/…/Settings
/[Advanced]/Privacy and Security/Security/Manage certificates

Import RootCA.crt

enter image description here

The browser will show this valid certificate tree:


RootCA-CA
  |_____ xhost.local

enter image description here

No Certificate Error will appear through LAN, even through WAN by https://dev.example.org.

enter image description here

Here is the whole Powershell Script socrt.ps1 file to generate all required certificate files from the naught:


#
# Generate:
#   RootCA.pem, RootCA.key RootCA.crt
#
#   xhost.key xhost.csr xhost.crt
#   xhost.pfx
#
# created  15-EEC-2020
# modified 15-DEC-2020
#
#
# change to a safe directory:
#

cd C:\users\so\crt

#
# Generate RootCA.pem, RootCA.key & RootCA.crt as Certification Authority:
#
openssl req -x509 -nodes -new -sha256 -days 10240 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=ZA/CN=RootCA-CA"
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt

#
# get RootCA.pfx: permitting to import into iis10: not required.
#
#openssl pkcs12 -export -out RootCA.pfx -inkey RootCA.key -in RootCA.crt

#
# get xhost.key xhost.csr:
#   C: Country
#   ST: State
#   L: locality (city)
#   O: Organization Name
#   OU: Organization Unit
#   CN: Common Name
#
openssl req -new -nodes -newkey rsa:2048 -keyout xhost.key -out xhost.csr -subj "/C=ZA/ST=FREE STATE/L=Golden Gate Highlands National Park/O=WWF4ME/OU=xhost.home/CN=xhost.local"

#
# get xhost.crt certified by RootCA.pem:
# to show content:
#   openssl x509 -in xhost.crt -noout -text
#
openssl x509 -req -sha256 -days 1024 -in xhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out xhost.crt

#
# get xhost.pfx, permitting to import into iis:
#
openssl pkcs12 -export -out xhost.pfx -inkey xhost.key -in xhost.crt

#
# import xhost.pfx in iis10 installed in xhost computer (here localhost).
#

To install openSSL for Windows, please visit https://slproweb.com/products/Win32OpenSSL.html

红ご颜醉 2024-12-24 01:10:17

如果您想要快速简单,请运行此

        var enabled   = false;
        if(enabled){
              window.onload   = e=>{
                    var today       = new Date();
                    var one_year    = new Date();
                    one_year.setFullYear(one_year.getFullYear()+1);
                    
                    var config      = {};
                    
                    config.from     = today;
                    config.to       = one_year;
                    
                    config.dns      = ['localhost'];
                    config.ip       = ['127.0.0.1','127.0.0.2'];
                    
                    config.rdn      = {};
                    
                    config.rdn.cn   = 'localhost test certificate';
                    config.rdn.o    = 'Test';
                    config.rdn.ou   = 'test';
                    config.rdn.l    = 'Blacksburg';
                    config.rdn.st   = 'Virginia';
                    config.rdn.c    = 'US';
                    
                    generate_certificate(config);
              };
        }

        
        $('#tab-config').onclick                                    = e=>show('config');
        $('#tab-cert').onclick                                      = e=>show('cert');
        
        $('#config-btns [value="generate certificate"]').onclick    = read;
        $('#config-btns [value=clear]').onclick                     = clear;
        $('#config-btns [value=localhost]').onclick                 = localhost;
        
        var rdns                                                    = ['cn','o','ou','l','st','c'];
        var list                                                    = {};
        list.dns                                                    = $('#dns-list');
        list.ip                                                     = $('#ip-list');
        var item                                                    = {};
        item.dns                                                    = $(list.dns,'.item');
        item.ip                                                     = $(list.ip,'.item');
        
        $('#dns-root [value=add]').onclick                          = e=>create('dns');
        $('#ip-root [value=add]').onclick                           = e=>create('ip');
            
        $('#from').value                                            = date();
        $('#to').value                                              = date(true);


        localhost();


        function localhost(){
              clear(true);
              $('#cn').value    = 'localhost test certificate';
              ['localhost'].forEach(value=>create('dns',value));
              ['127.0.0.1','127.0.0.2'].forEach(value=>create('ip',value))
        }
        
        function $(root,sel){
              if(!sel){sel=root;root=document};
              return root.querySelector(sel);
        }
        
        function create(type,value){
              var nitem                           = item[type].cloneNode(true);
              $(nitem,'.rem').onclick             = e=>nitem.remove();
              if(value)$(nitem,'.value').value    = value;
              list[type].append(nitem);
        }
        
        function clear(mode){
              rdns.forEach(name=>$('#'+name).value    = '');
              list.dns.replaceChildren();
              if(!mode)create('dns');
              list.ip.replaceChildren();
              if(!mode)create('ip');
        }
        
        function date(adj){
              var now       = new Date();
              var offset    = now.getTimezoneOffset()*60000;
              var local     = new Date(now.getTime()-offset);
              if(adj){
                    local.setFullYear(local.getFullYear()+1);
              }
              var date      = local.toISOString().substring(0,16);
              return date;
        }
        
        function read(){
              var config    = {};
              config.rdn    = {};
              rdns.forEach(name=>config.rdn[name]=$('#'+name).value);
              var arr       = type=>[...list[type].querySelectorAll('.item')].map(node=>$(node,'.value').value).filter(v=>v);
              config.dns    = arr('dns');
              config.ip     = arr('ip');
              config.from   = new Date($('#from').value);
              config.to     = new Date($('#to').value);
              
              generate_certificate(config);
        };
        
        function generate_certificate(config){
          
              var {key,cert,forge_cert}       = generateCertificate(config);
              
              show('cert');
              
              $('#key-copy').onclick          = e=>copy(key,$('#key'));
              $('#key-download').href        = window.URL.createObjectURL(new Blob([key]));
              $('#key-download').download    = 'private-key.pem';
              $('#key-download').onclick    = e=>download('private-key.pem',key);
              
              $('#x509-copy').onclick         = e=>copy(cert,$('#x509'));
              $('#x509-download').href        = window.URL.createObjectURL(new Blob([cert]));
              $('#x509-download').download    ='server-cert.pem';
              $('#x509-download').onclick   = e=>download('server-cert.pem',cert);
              
              $('#key').value                 = key
              $('#x509').value                = cert;
                            
        };
        
        function show(name){
              if(name==='config'){
                    $('#tab-config').classList.remove('inactive');
                    $('#tab-config').classList.add('active');
                    $('#config').style.display    = '';
                    $('#tab-cert').classList.remove('active');
                    $('#tab-cert').classList.add('inactive');
                    $('#cert').style.display      = 'none';
              }else{
                    $('#tab-config').classList.remove('active');
                    $('#tab-config').classList.add('inactive');
                    $('#config').style.display    = 'none';
                    $('#tab-cert').classList.remove('inactive');
                    $('#tab-cert').classList.add('active');
                    $('#cert').style.display      = '';
              }
        }
        
        function download(filename,txt){
              var blob      = new Blob([txt]);
              var a         = $('a');
              a.download    = filename;
              a.href        = window.URL.createObjectURL(blob);
              a.click();
        }
        
        async function copy(txt){
            try {
              await navigator.clipboard.writeText(txt);
            }
            catch (error) {
              alert(error.message);
            }
        }
        
        function copy(text,textarea){
              if (!navigator.clipboard) {
                fallback();
                return;
              }
              navigator.clipboard.writeText(text).then(function() {
                console.log('Async: Copying to clipboard was successful!');
              }, function(err) {
                fallback();
              });
              
              function fallback(text) {
                
                textarea.focus();
                textarea.select();
                try{
                      var successful = document.execCommand('copy');
                      if(!successful){
                        alert('failed to copy');
                      }
                } 
                catch(err){
                      alert('unable to copy', err);
                }
              
                document.body.removeChild(textArea);
              }
          
        }
              html,body {
                margin:0;
              }
              section {
                font-family:arial;
                width:100%;
                height:200px;
                position:relative;
              }
              input {
                box-sizing:border-box;
                font-size:16px;
                font-weight:bold;
                padding:5px 10px;
              }
              
              #tabs {
                display:flex;
                cursor:pointer;
                margin-bottom:10px;
                text-align:center;
              }
              .tab {
                padding:5px 0;
                flex:1;
              }
              .active {
                background:lightyellow;
                border:1px solid lightblue;
              }
              
              .inactive {
                background:lightgray;
                border:1px solid dimgray;
              }

              #view {
                position:absolute;
                inset:35px 0 0 0;
              }
              
              #config {
                position:absolute;
                inset:0 0 0 0;
              }
              #config-btns input {
                margin-right:20px;
              }

              #config-body {
                overflow:auto;
                position:absolute;
                inset:30px 0 0 0;
                padding:10px;
              }
              
              .hdr {
                height:25px;
                margin:10px auto;
                background-color:whitesmoke;
                padding:5px 10px;
              }
              .hdr input{
                margin-left:20px;
              }
              
              
              #rdns {
                display:grid;
                grid-template-columns:auto 1fr;
                gap:5px 20px;
              }
              #rdns div:nth-of-type(odd) {
                white-space:nowrap;
                overflow:hidden;
                max-width:200px;
              }
              #rdns input {
                width:100%;
                box-sizing:border-box;
              }
                
              .item {
                display:flex;
                align-items:center;
              }
              .rem {
                margin-right:10px;
                color:red;
              }
              .item div:nth-of-type(2) {
                flex:1;
              }
              .value {
                width:100%
              }
              
              #dates {
                display:grid;
                grid-template-columns:100px auto;
                gap:5px 20px;
              }
              
              #cert {
                padding:0px 10px;
              }
              
              #cert > div {
                margin-bottom:10px;
              }
              
              #cert input {
                margin:auto 10px;
              }
              
              #cert-body {
                position:absolute;
                inset:80px 10px 0 10px;
                overflow:auto;
              }
              
              #cert-body {
                display:flex;
              }
              textarea {
                flex:1;
              }
              
              a {
                border-width:2px;
                border-style:inset;
                border-color:dimgray;
                background:buttonface;          
                font-weight:bold;
                font-size:12px;
                border-radius:3px;
                padding:5px 10px;
              }
        <section>
        
              <div id=tabs>
                    <div id=tab-config class='tab active'>config</div>
                    <div id=tab-cert class='tab inactive'>certificate</div>
              </div>
              
              <div id=view>
              
                    <div id=config>
                          <div id=config-btns><input type=button value=clear><input type=button value=localhost><input type=button value='generate certificate'></div>
                          <div id=config-body>
                                <div id=rdns-root>
                                      <div class=hdr>Relative Distinguished Names</div>
                                      <div id=rdns>
                                            <div>CommonName (CN) </div><div><input id=cn></div>
                                            <div>Organization (O) </div><div><input id=o></div>
                                            <div>OrganizationalUnit (OU) </div><div><input id=ou></div>
                                            <div>Locality (L) </div><div><input id=l></div>
                                            <div>StateOrProvince (ST) </div><div><input id=st></div>
                                            <div>CountryName (C) </div><div><input id=c></div>
                                      </div>
                                </div>
                                <div id=dns-root>
                                      <div class=hdr>dns names (example.com) <input type=button value=add></div>
                                      <div id=dns-list>
                                            <div class=item><input type=button value=x class=rem><div><input id=dns class=value></div></div>
                                      </div>
                                </div>
                                <div id=ip-root>
                                      <div class=hdr>ips (127.0.0.1) <input type=button value=add></div>
                                      <div id=ip-list>
                                            <div class=item><input type=button value=x class=rem><div><input id=ip class=value></div></div>
                                      </div>
                                </div>
                                <div id=dates-root>
                                      <div class=hdr>dates</div>
                                      <div id=dates>
                                            <div>from</div><input id=from type=datetime-local>
                                            <div>to</div><input id=to type=datetime-local>
                                      </div>
                                </div>
                          </div>
                    </div>
                    
                    <div id=cert style='display:none'>
                          <div>private key (pem) <input id=key-copy type=button value='copy to clipboard'><a id=key-download>download, right-click : save link as</a></div>
                          <div>x509 cert (pem) <input id=x509-copy type=button value='copy to clipboard'><a id=x509-download>download, right-click : save link as</a></div>
                          <div id=cert-body>
                                <textarea id=key></textarea>
                                <textarea id=x509></textarea>
                          </div>
                    </div>
                    
              </div>
            
        </section>


<script type="module">

        import nodeForge from 'https://cdn.jsdelivr.net/npm/node-forge/+esm';
        var pki                   = nodeForge.pki;
        
        window.generateCertificate=function(config){
          
              var keys                  = pki.rsa.generateKeyPair(2048);
              var cert                  = pki.createCertificate();
              
              cert.publicKey            = keys.publicKey;
              
              cert.serialNumber         = '01';
              cert.validity.notBefore   = config.from;
              cert.validity.notAfter    = config.to;
              
              var attrs   = [];
              rdns.forEach(name=>{if(config.rdn[name])attrs.push({shortName:name.toUpperCase(),value:config.rdn[name]})});

              cert.setSubject(attrs);
              cert.setIssuer(attrs);
      
              cert.setExtensions([
                    {
                          name                : 'basicConstraints',
                          cA                  : false
                    },
                    {
                          name                : 'keyUsage',
                          keyCertSign         : true,
                          digitalSignature    : true,
                          nonRepudiation      : true,
                          keyEncipherment     : true,
                          dataEncipherment    : true
                    },
                    {
                          name                : 'extKeyUsage',
                          serverAuth          : true,
                          clientAuth          : true,
                          codeSigning         : true,
                          emailProtection     : true,
                          timeStamping        : true
                    },
                    {
                          name                : 'nsCertType',
                          client              : true,
                          server              : true,
                          email               : true,
                          objsign             : true,
                          sslCA               : true,
                          emailCA             : true,
                          objCA               : true
                    },
                    {
                          name                : 'subjectAltName',
                          altNames            : [config.dns.map(dns=>{return {type:2,value:dns}}),config.ip.map(ip=>{return {type:7,ip}})].flat()
                    },
                    {
                          name                : 'subjectKeyIdentifier'
                    }
              ]);
              
              cert.sign(keys.privateKey);
              
              var key           = pki.privateKeyToPem(keys.privateKey);
              var cert          = pki.certificateToPem(cert);
              var forge_cert    = pki.certificateFromPem(cert);

              return {key,cert,forge_cert};
              
        };
</script>

这将立即为您生成一个带有私钥的自签名 x509 证书,在浏览器中

使用简单的 ui 在配置选项卡中设置您的专有名称、dns 名称、ip 地址和证书有效期日期范围,然后点击生成

您可以验证的 证书在线证书证书检查器/解码器

如果您希望您的证书自动受到信任,则必须将其安装到受信任的根存储中,遵循此问题的其他答案中的许多示例


如果您想要快速而仓促,请运行此

我为此创建了一个端点 runkit.com

runkit.com - 来源:生成 https 证书

runkit.com - 端点:生成https证书

(async()=>{
      
      var url   = 'https://javascript-2020.runkit.io/generate-https-certificate/branches/master/';

      var {key,cert}    = await fetch(url).then(res=>res.json());
      
      console.log(key);
      console.log(cert);
            
})();

端点支持帖子正文中的配置

(async()=>{

      var today         = new Date();
      var one_year      = new Date();
      one_year.setFullYear(one_year.getFullYear()+1);
      
      var config        = {};
      
      config.from       = today;
      config.to         = one_year;
      
      config.dns        = ['localhost'];
      config.ip         = ['127.0.0.1','127.0.0.2'];
      
      config.rdn        = {};
      
      config.rdn.cn     = 'localhost test certificate';
      config.rdn.o      = '';
      config.rdn.ou     = '';
      config.rdn.l      = '';
      config.rdn.st     = '';
      config.rdn.c      = '';
      
      var body          = JSON.stringify(config);
      var opts          = {method:'post',body};
      var {key,cert}    = await fetch('https://javascript-2020.runkit.io/generate-https-certificate/branches/master/',opts).then(res=>res.json());
      
      console.log(key);
      console.log(cert);
            
})();

可以从服务器代码中使用端点,如下所示,这

//server.mjs

      var {key,cert}    = await fetch('https://javascript-2020.runkit.io/generate-https-certificate/branches/master/').then(res=>res.json());
      
      require('https').createServer({key,cert},request).listen(3030);
      
      function request(req,res){
      
            res.end('boy meets world');
            
      }//request

  


是为 Node.js生成自签名证书和密钥的代码

删除脚本标签,注释导入语句并取消注释 require 行,这需要 npm install node-forge 它会在本地安装 node-forge 来工作,然后您只需删除该目录即可删除所有内容,

请参阅下面的替代 node.js 方法,该方法不需要安装

//
        import nodeForge from 'https://cdn.jsdelivr.net/npm/node-forge/+esm';
        //var nodeForge   = require('node-forge');
        
        var pki         = nodeForge.pki;


        var today       = new Date();
        var one_year    = new Date();
        one_year.setFullYear(one_year.getFullYear()+1);
        
        var config      = {};
        
        config.from     = today;
        config.to       = one_year;
        
        config.dns      = ['localhost'];
        config.ip       = ['127.0.0.1','127.0.0.2'];
        
        config.rdn      = {};
        
        config.rdn.cn   = 'localhost test certificate';
        config.rdn.o    = '';
        config.rdn.ou   = '';
        config.rdn.l    = '';
        config.rdn.st   = '';
        config.rdn.c    = '';

        
        var attrs       = [];
        for(var name in config.rdn){
        
            attrs.push({shortName:name.toUpperCase(),value:config.rdn[name]});
            
        }//for

        var altNames    = [config.dns.map(dns=>{return {type:2,value:dns}}),config.ip.map(ip=>{return {type:7,ip}})].flat();

    
        var keys                  = pki.rsa.generateKeyPair(2048);
        var cert                  = pki.createCertificate();
        
        cert.publicKey            = keys.publicKey;
        
        cert.serialNumber         = '01';
        cert.validity.notBefore   = config.from;
        cert.validity.notAfter    = config.to;
        
        cert.setSubject(attrs);
        cert.setIssuer(attrs);

        cert.setExtensions([
              {
                    name                : 'basicConstraints',
                    cA                  : false
              },
              {
                    name                : 'keyUsage',
                    keyCertSign         : true,
                    digitalSignature    : true,
                    nonRepudiation      : true,
                    keyEncipherment     : true,
                    dataEncipherment    : true
              },
              {
                    name                : 'extKeyUsage',
                    serverAuth          : true,
                    clientAuth          : true,
                    codeSigning         : true,
                    emailProtection     : true,
                    timeStamping        : true
              },
              {
                    name                : 'nsCertType',
                    client              : true,
                    server              : true,
                    email               : true,
                    objsign             : true,
                    sslCA               : true,
                    emailCA             : true,
                    objCA               : true
              },
              {
                    name                : 'subjectAltName',
                    altNames            : [config.dns.map(dns=>{return {type:2,value:dns}}),config.ip.map(ip=>{return {type:7,ip}})].flat()
              },
              {
                    name                : 'subjectKeyIdentifier'
              }
        ]);
        
        cert.sign(keys.privateKey);
        
        var key     = pki.privateKeyToPem(keys.privateKey);
        var cert    = pki.certificateToPem(cert);


        console.log(key);
        console.log(cert);

我尝试使用 webpack 捆绑 node-forge 以便与 node.js url 导入一起使用,但有点不成功,stackoverflow 对答案的大小有限制,因此请访问撰写文章

github.io:捆绑node-forge

这是我必须解决的问题,在node.js中工作

//test.js

(async()=>{

      var nodeForge   = await fetch('https://raw.githubusercontent.com/javascript-2020/npm/main/node-forge/node-forge-nodejs-eval.js')
              .then(res=>res.text().then(txt=>new Promise(res=>{eval(txt);res(module.exports)})));
              
      console.log(nodeForge);
  
})();

我在 github.io :生成 https 证书

如果您想跟进此问题、讨论和其他很酷的内容,请加入我们 stackoverflow JavaScript 聊天

if you want it quick and easy, run this

        var enabled   = false;
        if(enabled){
              window.onload   = e=>{
                    var today       = new Date();
                    var one_year    = new Date();
                    one_year.setFullYear(one_year.getFullYear()+1);
                    
                    var config      = {};
                    
                    config.from     = today;
                    config.to       = one_year;
                    
                    config.dns      = ['localhost'];
                    config.ip       = ['127.0.0.1','127.0.0.2'];
                    
                    config.rdn      = {};
                    
                    config.rdn.cn   = 'localhost test certificate';
                    config.rdn.o    = 'Test';
                    config.rdn.ou   = 'test';
                    config.rdn.l    = 'Blacksburg';
                    config.rdn.st   = 'Virginia';
                    config.rdn.c    = 'US';
                    
                    generate_certificate(config);
              };
        }

        
        $('#tab-config').onclick                                    = e=>show('config');
        $('#tab-cert').onclick                                      = e=>show('cert');
        
        $('#config-btns [value="generate certificate"]').onclick    = read;
        $('#config-btns [value=clear]').onclick                     = clear;
        $('#config-btns [value=localhost]').onclick                 = localhost;
        
        var rdns                                                    = ['cn','o','ou','l','st','c'];
        var list                                                    = {};
        list.dns                                                    = $('#dns-list');
        list.ip                                                     = $('#ip-list');
        var item                                                    = {};
        item.dns                                                    = $(list.dns,'.item');
        item.ip                                                     = $(list.ip,'.item');
        
        $('#dns-root [value=add]').onclick                          = e=>create('dns');
        $('#ip-root [value=add]').onclick                           = e=>create('ip');
            
        $('#from').value                                            = date();
        $('#to').value                                              = date(true);


        localhost();


        function localhost(){
              clear(true);
              $('#cn').value    = 'localhost test certificate';
              ['localhost'].forEach(value=>create('dns',value));
              ['127.0.0.1','127.0.0.2'].forEach(value=>create('ip',value))
        }
        
        function $(root,sel){
              if(!sel){sel=root;root=document};
              return root.querySelector(sel);
        }
        
        function create(type,value){
              var nitem                           = item[type].cloneNode(true);
              $(nitem,'.rem').onclick             = e=>nitem.remove();
              if(value)$(nitem,'.value').value    = value;
              list[type].append(nitem);
        }
        
        function clear(mode){
              rdns.forEach(name=>$('#'+name).value    = '');
              list.dns.replaceChildren();
              if(!mode)create('dns');
              list.ip.replaceChildren();
              if(!mode)create('ip');
        }
        
        function date(adj){
              var now       = new Date();
              var offset    = now.getTimezoneOffset()*60000;
              var local     = new Date(now.getTime()-offset);
              if(adj){
                    local.setFullYear(local.getFullYear()+1);
              }
              var date      = local.toISOString().substring(0,16);
              return date;
        }
        
        function read(){
              var config    = {};
              config.rdn    = {};
              rdns.forEach(name=>config.rdn[name]=$('#'+name).value);
              var arr       = type=>[...list[type].querySelectorAll('.item')].map(node=>$(node,'.value').value).filter(v=>v);
              config.dns    = arr('dns');
              config.ip     = arr('ip');
              config.from   = new Date($('#from').value);
              config.to     = new Date($('#to').value);
              
              generate_certificate(config);
        };
        
        function generate_certificate(config){
          
              var {key,cert,forge_cert}       = generateCertificate(config);
              
              show('cert');
              
              $('#key-copy').onclick          = e=>copy(key,$('#key'));
              $('#key-download').href        = window.URL.createObjectURL(new Blob([key]));
              $('#key-download').download    = 'private-key.pem';
              $('#key-download').onclick    = e=>download('private-key.pem',key);
              
              $('#x509-copy').onclick         = e=>copy(cert,$('#x509'));
              $('#x509-download').href        = window.URL.createObjectURL(new Blob([cert]));
              $('#x509-download').download    ='server-cert.pem';
              $('#x509-download').onclick   = e=>download('server-cert.pem',cert);
              
              $('#key').value                 = key
              $('#x509').value                = cert;
                            
        };
        
        function show(name){
              if(name==='config'){
                    $('#tab-config').classList.remove('inactive');
                    $('#tab-config').classList.add('active');
                    $('#config').style.display    = '';
                    $('#tab-cert').classList.remove('active');
                    $('#tab-cert').classList.add('inactive');
                    $('#cert').style.display      = 'none';
              }else{
                    $('#tab-config').classList.remove('active');
                    $('#tab-config').classList.add('inactive');
                    $('#config').style.display    = 'none';
                    $('#tab-cert').classList.remove('inactive');
                    $('#tab-cert').classList.add('active');
                    $('#cert').style.display      = '';
              }
        }
        
        function download(filename,txt){
              var blob      = new Blob([txt]);
              var a         = $('a');
              a.download    = filename;
              a.href        = window.URL.createObjectURL(blob);
              a.click();
        }
        
        async function copy(txt){
            try {
              await navigator.clipboard.writeText(txt);
            }
            catch (error) {
              alert(error.message);
            }
        }
        
        function copy(text,textarea){
              if (!navigator.clipboard) {
                fallback();
                return;
              }
              navigator.clipboard.writeText(text).then(function() {
                console.log('Async: Copying to clipboard was successful!');
              }, function(err) {
                fallback();
              });
              
              function fallback(text) {
                
                textarea.focus();
                textarea.select();
                try{
                      var successful = document.execCommand('copy');
                      if(!successful){
                        alert('failed to copy');
                      }
                } 
                catch(err){
                      alert('unable to copy', err);
                }
              
                document.body.removeChild(textArea);
              }
          
        }
              html,body {
                margin:0;
              }
              section {
                font-family:arial;
                width:100%;
                height:200px;
                position:relative;
              }
              input {
                box-sizing:border-box;
                font-size:16px;
                font-weight:bold;
                padding:5px 10px;
              }
              
              #tabs {
                display:flex;
                cursor:pointer;
                margin-bottom:10px;
                text-align:center;
              }
              .tab {
                padding:5px 0;
                flex:1;
              }
              .active {
                background:lightyellow;
                border:1px solid lightblue;
              }
              
              .inactive {
                background:lightgray;
                border:1px solid dimgray;
              }

              #view {
                position:absolute;
                inset:35px 0 0 0;
              }
              
              #config {
                position:absolute;
                inset:0 0 0 0;
              }
              #config-btns input {
                margin-right:20px;
              }

              #config-body {
                overflow:auto;
                position:absolute;
                inset:30px 0 0 0;
                padding:10px;
              }
              
              .hdr {
                height:25px;
                margin:10px auto;
                background-color:whitesmoke;
                padding:5px 10px;
              }
              .hdr input{
                margin-left:20px;
              }
              
              
              #rdns {
                display:grid;
                grid-template-columns:auto 1fr;
                gap:5px 20px;
              }
              #rdns div:nth-of-type(odd) {
                white-space:nowrap;
                overflow:hidden;
                max-width:200px;
              }
              #rdns input {
                width:100%;
                box-sizing:border-box;
              }
                
              .item {
                display:flex;
                align-items:center;
              }
              .rem {
                margin-right:10px;
                color:red;
              }
              .item div:nth-of-type(2) {
                flex:1;
              }
              .value {
                width:100%
              }
              
              #dates {
                display:grid;
                grid-template-columns:100px auto;
                gap:5px 20px;
              }
              
              #cert {
                padding:0px 10px;
              }
              
              #cert > div {
                margin-bottom:10px;
              }
              
              #cert input {
                margin:auto 10px;
              }
              
              #cert-body {
                position:absolute;
                inset:80px 10px 0 10px;
                overflow:auto;
              }
              
              #cert-body {
                display:flex;
              }
              textarea {
                flex:1;
              }
              
              a {
                border-width:2px;
                border-style:inset;
                border-color:dimgray;
                background:buttonface;          
                font-weight:bold;
                font-size:12px;
                border-radius:3px;
                padding:5px 10px;
              }
        <section>
        
              <div id=tabs>
                    <div id=tab-config class='tab active'>config</div>
                    <div id=tab-cert class='tab inactive'>certificate</div>
              </div>
              
              <div id=view>
              
                    <div id=config>
                          <div id=config-btns><input type=button value=clear><input type=button value=localhost><input type=button value='generate certificate'></div>
                          <div id=config-body>
                                <div id=rdns-root>
                                      <div class=hdr>Relative Distinguished Names</div>
                                      <div id=rdns>
                                            <div>CommonName (CN) </div><div><input id=cn></div>
                                            <div>Organization (O) </div><div><input id=o></div>
                                            <div>OrganizationalUnit (OU) </div><div><input id=ou></div>
                                            <div>Locality (L) </div><div><input id=l></div>
                                            <div>StateOrProvince (ST) </div><div><input id=st></div>
                                            <div>CountryName (C) </div><div><input id=c></div>
                                      </div>
                                </div>
                                <div id=dns-root>
                                      <div class=hdr>dns names (example.com) <input type=button value=add></div>
                                      <div id=dns-list>
                                            <div class=item><input type=button value=x class=rem><div><input id=dns class=value></div></div>
                                      </div>
                                </div>
                                <div id=ip-root>
                                      <div class=hdr>ips (127.0.0.1) <input type=button value=add></div>
                                      <div id=ip-list>
                                            <div class=item><input type=button value=x class=rem><div><input id=ip class=value></div></div>
                                      </div>
                                </div>
                                <div id=dates-root>
                                      <div class=hdr>dates</div>
                                      <div id=dates>
                                            <div>from</div><input id=from type=datetime-local>
                                            <div>to</div><input id=to type=datetime-local>
                                      </div>
                                </div>
                          </div>
                    </div>
                    
                    <div id=cert style='display:none'>
                          <div>private key (pem) <input id=key-copy type=button value='copy to clipboard'><a id=key-download>download, right-click : save link as</a></div>
                          <div>x509 cert (pem) <input id=x509-copy type=button value='copy to clipboard'><a id=x509-download>download, right-click : save link as</a></div>
                          <div id=cert-body>
                                <textarea id=key></textarea>
                                <textarea id=x509></textarea>
                          </div>
                    </div>
                    
              </div>
            
        </section>


<script type="module">

        import nodeForge from 'https://cdn.jsdelivr.net/npm/node-forge/+esm';
        var pki                   = nodeForge.pki;
        
        window.generateCertificate=function(config){
          
              var keys                  = pki.rsa.generateKeyPair(2048);
              var cert                  = pki.createCertificate();
              
              cert.publicKey            = keys.publicKey;
              
              cert.serialNumber         = '01';
              cert.validity.notBefore   = config.from;
              cert.validity.notAfter    = config.to;
              
              var attrs   = [];
              rdns.forEach(name=>{if(config.rdn[name])attrs.push({shortName:name.toUpperCase(),value:config.rdn[name]})});

              cert.setSubject(attrs);
              cert.setIssuer(attrs);
      
              cert.setExtensions([
                    {
                          name                : 'basicConstraints',
                          cA                  : false
                    },
                    {
                          name                : 'keyUsage',
                          keyCertSign         : true,
                          digitalSignature    : true,
                          nonRepudiation      : true,
                          keyEncipherment     : true,
                          dataEncipherment    : true
                    },
                    {
                          name                : 'extKeyUsage',
                          serverAuth          : true,
                          clientAuth          : true,
                          codeSigning         : true,
                          emailProtection     : true,
                          timeStamping        : true
                    },
                    {
                          name                : 'nsCertType',
                          client              : true,
                          server              : true,
                          email               : true,
                          objsign             : true,
                          sslCA               : true,
                          emailCA             : true,
                          objCA               : true
                    },
                    {
                          name                : 'subjectAltName',
                          altNames            : [config.dns.map(dns=>{return {type:2,value:dns}}),config.ip.map(ip=>{return {type:7,ip}})].flat()
                    },
                    {
                          name                : 'subjectKeyIdentifier'
                    }
              ]);
              
              cert.sign(keys.privateKey);
              
              var key           = pki.privateKeyToPem(keys.privateKey);
              var cert          = pki.certificateToPem(cert);
              var forge_cert    = pki.certificateFromPem(cert);

              return {key,cert,forge_cert};
              
        };
</script>

this will generate you a self-signed x509 certificate with private key right now, here in the browser

set your distinguished names, dns names, ip addresses and certificate validity date ranges in the config tab using the simple ui and hit generate certificate

you can verify the certificate online certificate checker / decoder

if you want your certificate to be trusted automatically, you'd have to install it into the trusted root store, following any of the many examples in the other answers to this question


if you want it quick and hasty, run this

i created an endpoint for this on runkit.com

runkit.com - source : generate https certificate

runkit.com - endpoint : generate https certificate

(async()=>{
      
      var url   = 'https://javascript-2020.runkit.io/generate-https-certificate/branches/master/';

      var {key,cert}    = await fetch(url).then(res=>res.json());
      
      console.log(key);
      console.log(cert);
            
})();

the endpoint supports the config in the post body

(async()=>{

      var today         = new Date();
      var one_year      = new Date();
      one_year.setFullYear(one_year.getFullYear()+1);
      
      var config        = {};
      
      config.from       = today;
      config.to         = one_year;
      
      config.dns        = ['localhost'];
      config.ip         = ['127.0.0.1','127.0.0.2'];
      
      config.rdn        = {};
      
      config.rdn.cn     = 'localhost test certificate';
      config.rdn.o      = '';
      config.rdn.ou     = '';
      config.rdn.l      = '';
      config.rdn.st     = '';
      config.rdn.c      = '';
      
      var body          = JSON.stringify(config);
      var opts          = {method:'post',body};
      var {key,cert}    = await fetch('https://javascript-2020.runkit.io/generate-https-certificate/branches/master/',opts).then(res=>res.json());
      
      console.log(key);
      console.log(cert);
            
})();

the endpoint could be utilised from server code like this

//server.mjs

      var {key,cert}    = await fetch('https://javascript-2020.runkit.io/generate-https-certificate/branches/master/').then(res=>res.json());
      
      require('https').createServer({key,cert},request).listen(3030);
      
      function request(req,res){
      
            res.end('boy meets world');
            
      }//request

  


heres the code for generating a self signed certificate and key

for node.js delete the script tags, comment the import statement and uncomment the require line, this requires npm install node-forge which installs node-forge locally to work, you can then just delete the directory to get rid of everything

see below for an alternative node.js method which does not require installing

//
        import nodeForge from 'https://cdn.jsdelivr.net/npm/node-forge/+esm';
        //var nodeForge   = require('node-forge');
        
        var pki         = nodeForge.pki;


        var today       = new Date();
        var one_year    = new Date();
        one_year.setFullYear(one_year.getFullYear()+1);
        
        var config      = {};
        
        config.from     = today;
        config.to       = one_year;
        
        config.dns      = ['localhost'];
        config.ip       = ['127.0.0.1','127.0.0.2'];
        
        config.rdn      = {};
        
        config.rdn.cn   = 'localhost test certificate';
        config.rdn.o    = '';
        config.rdn.ou   = '';
        config.rdn.l    = '';
        config.rdn.st   = '';
        config.rdn.c    = '';

        
        var attrs       = [];
        for(var name in config.rdn){
        
            attrs.push({shortName:name.toUpperCase(),value:config.rdn[name]});
            
        }//for

        var altNames    = [config.dns.map(dns=>{return {type:2,value:dns}}),config.ip.map(ip=>{return {type:7,ip}})].flat();

    
        var keys                  = pki.rsa.generateKeyPair(2048);
        var cert                  = pki.createCertificate();
        
        cert.publicKey            = keys.publicKey;
        
        cert.serialNumber         = '01';
        cert.validity.notBefore   = config.from;
        cert.validity.notAfter    = config.to;
        
        cert.setSubject(attrs);
        cert.setIssuer(attrs);

        cert.setExtensions([
              {
                    name                : 'basicConstraints',
                    cA                  : false
              },
              {
                    name                : 'keyUsage',
                    keyCertSign         : true,
                    digitalSignature    : true,
                    nonRepudiation      : true,
                    keyEncipherment     : true,
                    dataEncipherment    : true
              },
              {
                    name                : 'extKeyUsage',
                    serverAuth          : true,
                    clientAuth          : true,
                    codeSigning         : true,
                    emailProtection     : true,
                    timeStamping        : true
              },
              {
                    name                : 'nsCertType',
                    client              : true,
                    server              : true,
                    email               : true,
                    objsign             : true,
                    sslCA               : true,
                    emailCA             : true,
                    objCA               : true
              },
              {
                    name                : 'subjectAltName',
                    altNames            : [config.dns.map(dns=>{return {type:2,value:dns}}),config.ip.map(ip=>{return {type:7,ip}})].flat()
              },
              {
                    name                : 'subjectKeyIdentifier'
              }
        ]);
        
        cert.sign(keys.privateKey);
        
        var key     = pki.privateKeyToPem(keys.privateKey);
        var cert    = pki.certificateToPem(cert);


        console.log(key);
        console.log(cert);

i attempted to use webpack to bundle node-forge for use with node.js url imports, but was somewhat unsuccessful, stackoverflow has a limit on how big answers can be so please visit for a write up

github.io : bundling node-forge

this is what i had to settle on, works in node.js

//test.js

(async()=>{

      var nodeForge   = await fetch('https://raw.githubusercontent.com/javascript-2020/npm/main/node-forge/node-forge-nodejs-eval.js')
              .then(res=>res.text().then(txt=>new Promise(res=>{eval(txt);res(module.exports)})));
              
      console.log(nodeForge);
  
})();

i created a more thorough web-ui on github.io : generate https certificate

if you want to follow up on this, discuss and other cool stuff come join us in the stackoverflow javascript chat

我做我的改变 2024-12-24 01:10:17

你可以尝试 mkcert。

Macos:brew安装mkcert

you could try mkcert.

macos: brew install mkcert

屌丝范 2024-12-24 01:10:17

以下是我在 Windows 上为 localhost 获取有效证书所做的操作:

  1. 下载 mkcert 可执行文件 (https://github.com/mkcert/mkcert/mkcert/mkcert/mkcert.html com/FiloSottile/mkcert/releases)并将其重命名为 mkcert.exe
  2. 运行“mkcert -install”
  3. 打开 Windows 证书管理器 (certmgr.msc)
  4. 右键单击​​“受信任”根证书颁发机构”->导入
  5. 从 C:\Users[用户名]\AppData\Local\mkcert\ 导入根证书 (rootCA.pem)
  6. 为指定域创建 *.p12 证书:“mkcert -pkcs12 [name1] [name2]”
  7. 重命名 * .p12 证书转换为 *.pfx
  8. 在 IIS 中 ->服务器证书 ->在“个人”组中导入(pfx)[默认密码:“changeit”]
  9. 将证书分配给默认网站(绑定 -> https (443) -> 修改 -> SSL 证书)

Here's what I did to get a valid certificate for localhost on Windows:

  1. Download mkcert executable (https://github.com/FiloSottile/mkcert/releases) and rename it to mkcert.exe
  2. Run "mkcert -install"
  3. Open Windows certificate manager (certmgr.msc)
  4. Right click on "Trusted Root Certification Authorities" -> Import
  5. Import Root cert (rootCA.pem) from C:\Users[username]\AppData\Local\mkcert\
  6. Create a *.p12 certificate for specified domain(s): "mkcert -pkcs12 [name1] [name2]"
  7. Rename *.p12 certificate into *.pfx
  8. In IIS -> Server Certificates -> Import (pfx) in "Personal" group [default password: "changeit"]
  9. Assign certificate to Default Web Site (binding -> https (443) -> modify -> SSL certificate)
天冷不及心凉 2024-12-24 01:10:17

适用于 Windows 10 的解决方案

以上均不适合我,但这个:

1。 按照以下步骤

$cert = New-SelfSignedCertificate -Subject local.YourDomain -DnsName local.yourdomain.co.uk

然后

Format-List -Property *

或此处创建具有单一主题的证书下的步骤进行操作:https://adamtheautomator.com/new-selfsignedcertificate/

您还可以尝试 SAN(创建主题备用名称 (SAN) 证书)。

2.打开 mmc

打开 Windows 搜索并输入 mmc

然后按照以下步骤操作:

打开文件 > > 添加/删除管理单元,选择证书并单击添加。选择计算机帐户,单击下一步,然后单击完成

3.将证书从个人复制到受信任

展开 mmc证书下的个人

个人复制新证书受信任的根证书颁发机构

4。为您在 IIS 中的域绑定选择新证书

5.重新启动域/站点

Solution for Windows 10

None of the above worked for me but this one:

1. Follow these steps

$cert = New-SelfSignedCertificate -Subject local.YourDomain -DnsName local.yourdomain.co.uk

then

Format-List -Property *

or steps under Creating A Certificate With a Single Subject here: https://adamtheautomator.com/new-selfsignedcertificate/

You can also try SAN (Creating A Subject Alternative Name (SAN) Certificate).

2. Open mmc

Open Windows search and type mmc

then follow these steps:

Open File > Add/Remove Snap-in, select Certificates and click Add. Select Computer account, click Next and then Finish.

3. Copy certificate from Personal to Trusted

Expand Personal under Certificates in mmc

Copy your new certificate from Personal to Trusted Root Certification Authorities

4. Select the new certificate for your domain binding in IIS

5. Restart the domain/ site

柠栀 2024-12-24 01:10:17

这些是生成 SSL 密钥和证书所需的 OpenSSL 命令。

1.  openssl genpkey -algorithm RSA -out rootCA.key -aes256
2.  req -new -key server.key -out server.csr -config openssl.cnf -extensions v3_req
3.  genpkey -algorithm RSA -out server.key -aes256
4.  openssl req -new -key server.key -out server.csr -config openssl.cnf -extensions v3_req
5.  openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile openssl.cnf -extensions v3_req
6.  openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -certfile rootCA.pem -password pass:yourpassphrase

这里使用的配置文件“openssl.cnf”如下:

[ req ]
default_bits       = 2048
default_md         = sha256
default_keyfile    = privkey.pem
distinguished_name = req_distinguished_name
x509_extensions    = v3_ca
string_mask        = utf8only

[ req_distinguished_name ]
countryName                     = PK
countryName_default             = PK
stateOrProvinceName             = SND
stateOrProvinceName_default     = SND
localityName                    = KHI
localityName_default            = KHI
organizationName                = MyOrg
organizationName_default        = MyOrg
organizationalUnitName          = RnD
commonName                      = CertificateNameToDisplay
commonName_max                  = 64

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, cRLSign, keyCertSign

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = localhost

检查“localhost”的最后一个 DNS 行。请记住您在第 1 步和第 2 步中提供的密码。 6.

These are the OpenSSL commands need to generate SSL keys and certificates.

1.  openssl genpkey -algorithm RSA -out rootCA.key -aes256
2.  req -new -key server.key -out server.csr -config openssl.cnf -extensions v3_req
3.  genpkey -algorithm RSA -out server.key -aes256
4.  openssl req -new -key server.key -out server.csr -config openssl.cnf -extensions v3_req
5.  openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile openssl.cnf -extensions v3_req
6.  openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -certfile rootCA.pem -password pass:yourpassphrase

The configuration file "openssl.cnf" used here is following:

[ req ]
default_bits       = 2048
default_md         = sha256
default_keyfile    = privkey.pem
distinguished_name = req_distinguished_name
x509_extensions    = v3_ca
string_mask        = utf8only

[ req_distinguished_name ]
countryName                     = PK
countryName_default             = PK
stateOrProvinceName             = SND
stateOrProvinceName_default     = SND
localityName                    = KHI
localityName_default            = KHI
organizationName                = MyOrg
organizationName_default        = MyOrg
organizationalUnitName          = RnD
commonName                      = CertificateNameToDisplay
commonName_max                  = 64

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, cRLSign, keyCertSign

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = localhost

Check the last DNS line for "localhost". And be remember you password provided in step 1 & 6.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文