Skip to content

Commit c1a5923

Browse files
save file
1 parent bfef807 commit c1a5923

File tree

1 file changed

+397
-0
lines changed

1 file changed

+397
-0
lines changed
Lines changed: 397 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,397 @@
1+
2+
3+
4+
<!DOCTYPE html>
5+
6+
<html>
7+
8+
<head>
9+
<meta charset=utf-8>
10+
11+
<title>
12+
Extract Public Key
13+
</title>
14+
15+
<meta name=description content='extract public key from x509 certificate'>
16+
17+
<base href='https://ext-code.com/utils/x509/extract-public-key/'>
18+
<link rel=canonical href='https://ext-code.com/utils/x509/extract-public-key/extract-public-key.html'>
19+
20+
<link rel=icon type='image/x-icon' href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAz1BMVEVHcExFjOkWsvNGjug9jOxBhesulvAMtfsqofAvoO4pn+8hqPA0j+4WtvQhoPQfuvENuPkYrPchsfMYrPcepfVFiOgqnPE5jO1CguofrfEbrPULufoLu/kIu/sUtfMRsfljr/Q+h+0tl/JmufcJuPwVrfiTz/kZqvcknPNRoPKky/um0vobp/YcpfZmo/NltfY1nvKUxvl7vvdJtPYtqPVDvfms1/o3q/VEku9Ki+09mfFZlfCb1/mfxPu54PmEx/q64/lsw/dTqvOUvflcsvflva1XAAAAH3RSTlMAKFwUi9XO/jUfW1zpJf4KqOcY1+1BrNHsPaPJhNJObHCDBwAAAM1JREFUKM/lkUcSgkAURAEJIyoK5sjA4ICggBJMiPH+Z5IRq3SBxQHs7avf1d2fov5aFZqu/IQ026/XebZaTLuctlssDjoPCm85zV3bsQN1vuie1fwguME49fSeKAIFAGrINJqzRp6K22/O5zVEaeJbltRpd+SRrLZbwvjF6cHxhCIHh9fLxvO87WppzueqKhhGq/nGjxDHUYYRQl94quTmdxtCjBNMzKUMmwQLxuQdzbVteAuikEQTa0QMUfVTzHHwj2Ils5SNWvaSP9QTHZEaQktZsJwAAAAASUVORK5CYII='>
21+
<meta name=viewport content='width=device-width, initial-scale=1'>
22+
23+
<script type='application/ld+json'>
24+
{
25+
"@context" : "https://schema.org",
26+
"@type" : "SoftwareApplication",
27+
"name" : "Extract Public Key From X509 Certificate",
28+
"url" : "https://ext-code.com/utils/x509/certificate-info/certificate-info.html",
29+
"author" : {"@type":"Person","name":"Matthew Richards"},
30+
"description" : "Extract public key from x509 certificate",
31+
"applicationCategory" : "DeveloperApplication",
32+
"operatingSystem" : "All",
33+
"browserRequirements" : "Requires JavaScript-enabled browser",
34+
"softwareVersion" : "1.0.0",
35+
"offers" : {"@type":"Offer","price":"0","priceCurrency":"GBP"}
36+
}
37+
</script>
38+
39+
40+
<script src='https://libs.ext-code.com/js/dom/component/component.js'></script>
41+
42+
<script init>
43+
console.clear();
44+
console.log('extract-public-key-v2.0.html');
45+
console.log();
46+
console.json=v=>console.log(JSON.stringify(v,null,4));
47+
var df=true,did='html'
48+
;
49+
50+
var ext;
51+
var $;
52+
var datatype;
53+
var menumod;
54+
var keydown;
55+
56+
var hdr;
57+
var filemod;
58+
var log;
59+
60+
61+
62+
63+
//:
64+
65+
66+
async function init(){
67+
68+
69+
await load();
70+
71+
72+
menu = menumod();
73+
74+
hdr = mod['x509-hdr'];
75+
//filemod = mod['file-mod'];
76+
log = mod['log-mod'];
77+
78+
79+
hdr.initmod({ext,$,menu});
80+
//filemod.initmod({ext,$,menu,menumod,complete,focus,source,editor,log});
81+
log.initmod({ext,$});
82+
83+
await Promise.all([
84+
hdr.init(),
85+
//filemod.init(),
86+
log.init(),
87+
]);
88+
89+
90+
91+
initdom(document.body);
92+
93+
94+
}//init
95+
96+
97+
(async()=>{
98+
99+
mod.stack.add;
100+
101+
({ext} = await import('https://libs.ext-code.com/js/io/ext-loader/ext-loader.m.js'));
102+
103+
var promise = ext.load.libs(
104+
'js/dom/$.js',
105+
'js/core/datatype.js',
106+
'js/dom/menumod/menumod.js',
107+
'js/dom/keydown/keydown.js',
108+
);
109+
[$,datatype,menumod,keydown] = await promise;
110+
111+
mod.stack.complete;
112+
113+
})();
114+
115+
116+
117+
118+
async function load(){
119+
120+
//var nodeForge = await import('https://cdn.jsdelivr.net/npm/node-forge/+esm');
121+
var txt = localStorage['node-forge'];
122+
123+
if(!txt){
124+
var url = 'https://cdn.jsdelivr.net/npm/node-forge/+esm';
125+
console.log(url);
126+
var res = await fetch(url);
127+
txt = await res.text();
128+
localStorage['node-forge'] = txt;
129+
}
130+
131+
var blob = new Blob([txt],{type:'text/javascript'});
132+
var url = window.URL.createObjectURL(blob);
133+
var nodeforge = await import(url);
134+
pki = nodeforge.default.pki;
135+
console.log(pki);
136+
}//load
137+
138+
139+
</script init>
140+
141+
142+
<style>
143+
144+
html
145+
{height:100%}
146+
body
147+
{height:calc(100% - 42px);margin:20px;display:flex;flex-direction:column;font-family:arial}
148+
.hdr
149+
{font-family:arial;position:relative;margin-top:0;margin-bottom:20px;background:white;
150+
padding-bottom:10px;border-bottom:3px solid lightblue}
151+
.hdr-icon
152+
{display:inline-block;text-align:center;background:whitesmoke;border-radius:5px;
153+
border:1px solid lightgray;padding:5px 3px 0px;cursor:pointer;margin-right:10px;
154+
min-width:50px}
155+
.hdr-icon-img
156+
{width:25px;height:25px}
157+
.hdr-icon-label
158+
{margin:2px 0 0}
159+
.hdr-title
160+
{position:absolute;left:0;right:0;z-index:0;margin:0 auto}
161+
.hdr-date
162+
{float:right}
163+
164+
input
165+
{padding:5px 10px;font-size:16px}
166+
input[type=button]
167+
{cursor:pointer}
168+
169+
#view
170+
{flex:1;display:flex;gap:10px}
171+
#cert-root
172+
{flex:1;display:flex;flex-direction:column}
173+
#cert
174+
{flex:1}
175+
#key-root
176+
{flex:1;display:flex;flex-direction:column}
177+
#key
178+
{flex:1}
179+
pre
180+
{border:1px solid lightgray;font-size:16px;font-family:monospace}
181+
182+
183+
.visually-hidden
184+
{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;
185+
clip:rect(0 0 0 0) !important;white-space:nowrap !important;border:0 !important}
186+
187+
188+
</style>
189+
190+
</head>
191+
192+
193+
<body>
194+
195+
<x509-hdr component=grp>
196+
<h1 class=visually-hidden>
197+
extract public key
198+
</h1>
199+
<img class=title src='images/extract-public-key.png' style='top:-5px;height:55px'>
200+
<time slot=date datetime=2025-11-15>
201+
15 Nov 2025
202+
</time>
203+
</x509-hdr>
204+
205+
206+
<!--
207+
<div class=hdr>
208+
<a class=hdr-icon href='https://javascript-2020.github.io/'>
209+
<img class=hdr-icon-img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAqFBMVEVHcEwjmpckopg9f3YxpJM6r5kjq58Nmp0Nn6QRoKExrpshnpgtoJUdoZwYnZ02spwYpaEmrZ8djpINn6Qtrp4inpcjqZ8SoqM3s5w0sp01spwrr58vr50oqpwdnpo0sZwtrJwUpKMMoaUtq50op5ssqpopppseqaM1sJwgpJ0NoaUSoaI3kYobqaMSpKQrr58PoaMVpaIOoKMLpKcXpaEkqp8Rm58YrKUL0CR4AAAAOHRSTlMACBkBCyinK59CQhUOLyKjqbUGpZgSYn6rp5WsekcmgkyWmCkmNB7AYTiuVgKuuo91i2PLn2lJ7kISMf4AAAElSURBVCjPrdPXloIwEAbgBDFKCRo6SO8lYEHd93+zxV7Zm2WuSL6Tk/MPEwBGLFH8SzFCeFiDXNeJ+7GtGds1D+ghDzzPzXX6xlJbq75s5KVLiJsSB76xIhd22Mz0pkyRnqzW2htD/SeUjL0EQKY60nqRvTLXGl64PR/SfDVxVvETZ123w8vN9Ur5YKUF4R9cd/WxqiePgCs3IMF1QXcVt6vK59tSqyjN4hwQbhS8mUuvWTLbwYtTQGhEjLHVPprv+4ztQ8AeRVn50uipBcXg/IPgfPaFF+z1axyeMEkcJwwdYHHZINQ02gALS49lJcQMci/COGzdue8apRQwNz4tYvM207JSRVEUhvtW6KeBIFVVbds07xPncZfCfWSK+UtNJ/9+VL/nTBuX7xjDZwAAAABJRU5ErkJggg==' />
210+
<div class=icon-label>
211+
home
212+
</div>
213+
</a>
214+
<a id=github class=hdr-icon href='https://github.com/javascript-2020/javascript-2020.github.io/tree/main/utils/x509/generate-certificate-chain/generate-certificate-chain.html'>
215+
<img class=hdr-icon-img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAbFJREFUOE/l1E2IT2EUx/HPIFI2lJfGwmYsxFZKEUWjKWM3pZSpKcqeBcpLZsNeUeNlZWdBSVFmkAXbmRWbWRCRjYW8jv+pc/V4utff3q3bvfc5z/k+557zO2dA97UHy7ERx3LbZbzEZzxscx3o4L3GWizusP/AO6yv7TXwAo5g9V8iL03vcRWnm8USeBHH/xFUb7uEE7HYAOMZeVmGm7iN61jVccBHjOMQxvAl870QoIDMZ87CfxR3E7QDTyroTjzOtf24k++R0w0BHMY9LEpDCeyXgRL4EyMBjEKcSs+o3r4uSbTQQ1r3CzVMBnCh2PimTQp9wgyJDZZV/g+Bz7E1c/AdezHdr7xp34UHvcIuye8XUZSy9A1nDT5UBSvPCL9oz9BeeY2GYR3msBIHsi834WlPTt9yrXQKIUdEIfoVhSG6Z3PTejdwGG+xDc9SPud7UZ6popjEyZaURMuOl8NhKvtzpKf4yGvMwk95l/5xwNkKeA0T5XCI96EcRbsLh5mWAtXARznyXtXA5tD4/YNYmuBzVTQN8Ctu5V/93tI1sbdjS463KxXwaFZ/NnP9h/kXPcNYElddRc0AAAAASUVORK5CYII='>
216+
<div class=hdr-icon-label>
217+
github
218+
</div>
219+
</a>
220+
221+
<img class=hdr-title src='images/extract-public-key.png' style='height:40px;top:0px'>
222+
223+
<div class=hdr-date>
224+
22 Apr 2025
225+
</div>
226+
</div hdr>
227+
-->
228+
229+
<div id=view>
230+
231+
<div id=cert-root>
232+
233+
<div>
234+
public certificate
235+
</div>
236+
<div>
237+
<input value=paste type=button>
238+
<input value=load type=button>
239+
<input value=extract type=button>
240+
</div>
241+
<pre id=cert>
242+
</pre>
243+
244+
</div>
245+
246+
<div id=key-root>
247+
248+
<div>
249+
public key
250+
</div>
251+
<div>
252+
<input value=copy type=button>
253+
<input value=save type=button>
254+
</div>
255+
<pre id=key>
256+
</pre>
257+
258+
</div>
259+
260+
</div>
261+
262+
263+
</body>
264+
265+
266+
<script>
267+
268+
269+
var pki;
270+
271+
var cert;
272+
var key;
273+
274+
275+
var btn = {};
276+
btn.cert = {};
277+
btn.key = {};
278+
279+
280+
//:
281+
282+
function initdom(){
283+
284+
var rootnode = document.body;
285+
286+
287+
hdr.initdom(rootnode);
288+
289+
290+
var root = {};
291+
292+
root.cert = $(rootnode,'#cert-root');
293+
294+
$(root.cert,'[value=paste]').onclick = btn.cert.paste;
295+
$(root.cert,'[value=load]').onclick = btn.cert.load;
296+
$(root.cert,'[value=extract]').onclick = btn.cert.extract;
297+
298+
cert = $(root.cert,'#cert');
299+
300+
301+
root.key = $(rootnode,'#key-root');
302+
303+
$(root.key,'[value=copy]').onclick = btn.key.copy;
304+
$(root.key,'[value=save]').onclick = btn.key.save;
305+
306+
key = $(root.key,'#key');
307+
308+
309+
310+
log.initdom();
311+
312+
}//initdom
313+
314+
315+
//:
316+
317+
318+
btn.cert.paste = async function(e){
319+
320+
var txt = await navigator.clipboard.readText();
321+
cert.textContent = txt;
322+
323+
}//paste
324+
325+
326+
btn.cert.load = function(e){
327+
328+
var input = document.createElement('input');
329+
input.type = 'file';
330+
input.onchange = onchange;
331+
input.click();
332+
333+
334+
async function onchange(){
335+
336+
var file = input.files[0];
337+
var txt = await file.text();
338+
cert.textContent = txt;
339+
340+
}//onchange
341+
342+
}//load
343+
344+
345+
btn.cert.extract = async function(e){
346+
347+
var pem = cert.textContent.trim();
348+
var pem = await extract(pem);
349+
key.textContent = pem;
350+
351+
}//extract
352+
353+
354+
btn.key.copy = async function(e){
355+
356+
var txt = key.textContent.trim();
357+
await navigator.clipboard.writeText(txt);
358+
359+
}//copy
360+
361+
362+
btn.key.save = function(e){
363+
364+
var txt = key.textContent.trim();
365+
var blob = new Blob([txt]);
366+
var url = window.URL.createObjectURL(blob);
367+
368+
var a = document.createElement('a');
369+
a.download = 'public-key.pem';
370+
a.href = url;
371+
a.click();
372+
373+
}//save
374+
375+
376+
377+
async function extract(pem){
378+
379+
var cert = pki.certificateFromPem(pem);
380+
var key = cert.publicKey;
381+
var pem = pki.publicKeyToPem(key);
382+
return pem;
383+
384+
}//extract
385+
386+
387+
388+
389+
390+
</script>
391+
392+
393+
394+
</html>
395+
396+
397+

0 commit comments

Comments
 (0)