Reputation: 37480
I've gone through the steps detailed in How do you use HTTPS and SSL on 'localhost'?, but this sets up a self-signed certificate for my machine name, and when browsing it via https://localhost, I receive the Internet Explorer warning.
Is there a way to create a self-signed certificate for "localhost" to avoid this warning?
Upvotes: 243
Views: 463665
Reputation: 636
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.
Upvotes: 1
Reputation: 519
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
Upvotes: 1
Reputation: 2263
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
Upvotes: 63
Reputation: 70184
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
.
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:
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.
Your certificate is now trusted:
Upvotes: 214
Reputation: 2156
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
Upvotes: 0
Reputation: 604
Here's what I did to get a valid certificate for localhost on Windows:
Upvotes: 1
Reputation: 6151
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")
Upvotes: 8
Reputation: 8741
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.
cd C:\users\so\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
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"
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
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
installed in xhost computer (here localhost). and Restart IIS service.
IIS10 Gestionnaire des services Internet (IIS) (%windir%\system32\inetsrv\InetMgr.exe)
Restart IIS Service.
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
The browser will show this valid certificate tree:
RootCA-CA
|_____ xhost.local
No Certificate Error will appear through LAN, even through WAN by https://dev.example.org.
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
Upvotes: 3
Reputation: 561
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.
Upvotes: 46
Reputation: 18932
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);
Upvotes: 116
Reputation: 7383
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.
Upvotes: 10
Reputation: 444
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
Upvotes: 23
Reputation: 7514
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
Upvotes: 3