Skip to content

Commit 41a1614

Browse files
committed
remove browserify-cipher, use crypto.subtle for nip04.
1 parent 0500415 commit 41a1614

7 files changed

+58
-35
lines changed

.eslintrc.json

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"document": false,
2525
"navigator": false,
2626
"window": false,
27+
"crypto": false,
2728
"location": false,
2829
"URL": false,
2930
"URLSearchParams": false,

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ let pk2 = getPublicKey(sk2)
171171

172172
// on the sender side
173173
let message = 'hello'
174-
let ciphertext = nip04.encrypt(sk1, pk2, 'hello')
174+
let ciphertext = await nip04.encrypt(sk1, pk2, 'hello')
175175

176176
let event = {
177177
kind: 4,
@@ -187,7 +187,7 @@ sendEvent(event)
187187
sub.on('event', (event) => {
188188
let sender = event.tags.find(([k, v]) => k === 'p' && && v && v !== '')[1]
189189
pk1 === sender
190-
let plaintext = nip04.decrypt(sk2, pk1, event.content)
190+
let plaintext = await nip04.decrypt(sk2, pk1, event.content)
191191
})
192192
```
193193

nip04.test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
const {nip04, getPublicKey, generatePrivateKey} = require('./lib/nostr.cjs')
44

5-
test('encrypt and decrypt message', () => {
5+
test('encrypt and decrypt message', async () => {
66
let sk1 = generatePrivateKey()
77
let sk2 = generatePrivateKey()
88
let pk1 = getPublicKey(sk1)
99
let pk2 = getPublicKey(sk2)
1010

11-
expect(nip04.decrypt(sk2, pk1, nip04.encrypt(sk1, pk2, 'hello'))).toEqual(
12-
'hello'
13-
)
11+
expect(
12+
await nip04.decrypt(sk2, pk1, await nip04.encrypt(sk1, pk2, 'hello'))
13+
).toEqual('hello')
1414
})

nip04.ts

+45-24
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,66 @@
1-
import {Buffer} from 'buffer'
21
import {randomBytes} from '@noble/hashes/utils'
32
import * as secp256k1 from '@noble/secp256k1'
4-
// @ts-ignore
5-
import aes from 'browserify-cipher'
3+
import {encode as b64encode, decode as b64decode} from 'base64-arraybuffer'
64

7-
export function encrypt(privkey: string, pubkey: string, text: string): string {
5+
import {utf8Decoder, utf8Encoder} from './utils'
6+
7+
export async function encrypt(
8+
privkey: string,
9+
pubkey: string,
10+
text: string
11+
): Promise<string> {
812
const key = secp256k1.getSharedSecret(privkey, '02' + pubkey)
913
const normalizedKey = getNormalizedX(key)
1014

1115
let iv = Uint8Array.from(randomBytes(16))
12-
var cipher = aes.createCipheriv(
13-
'aes-256-cbc',
14-
Buffer.from(normalizedKey, 'hex'),
15-
iv
16+
let plaintext = utf8Encoder.encode(text)
17+
let cryptoKey = await crypto.subtle.importKey(
18+
'raw',
19+
normalizedKey,
20+
{name: 'AES-CBC'},
21+
false,
22+
['encrypt']
1623
)
17-
let encryptedMessage = cipher.update(text, 'utf8', 'base64')
18-
encryptedMessage += cipher.final('base64')
24+
let ciphertext = await crypto.subtle.encrypt(
25+
{name: 'AES-CBC', iv},
26+
cryptoKey,
27+
plaintext
28+
)
29+
let ctb64 = b64encode(ciphertext)
30+
let ivb64 = b64encode(iv.buffer)
1931

20-
return `${encryptedMessage}?iv=${Buffer.from(iv.buffer).toString('base64')}`
32+
return `${ctb64}?iv=${ivb64}`
2133
}
2234

23-
export function decrypt(
35+
export async function decrypt(
2436
privkey: string,
2537
pubkey: string,
26-
ciphertext: string
27-
): string {
28-
let [cip, iv] = ciphertext.split('?iv=')
38+
data: string
39+
): Promise<string> {
40+
let [ctb64, ivb64] = data.split('?iv=')
2941
let key = secp256k1.getSharedSecret(privkey, '02' + pubkey)
3042
let normalizedKey = getNormalizedX(key)
3143

32-
var decipher = aes.createDecipheriv(
33-
'aes-256-cbc',
34-
Buffer.from(normalizedKey, 'hex'),
35-
Buffer.from(iv, 'base64')
44+
let cryptoKey = await crypto.subtle.importKey(
45+
'raw',
46+
normalizedKey,
47+
{name: 'AES-CBC'},
48+
false,
49+
['decrypt']
50+
)
51+
let ciphertext = b64decode(ctb64)
52+
let iv = b64decode(ivb64)
53+
54+
let plaintext = await crypto.subtle.decrypt(
55+
{name: 'AES-CBC', iv},
56+
cryptoKey,
57+
ciphertext
3658
)
37-
let decryptedMessage = decipher.update(cip, 'base64', 'utf8')
38-
decryptedMessage += decipher.final('utf8')
3959

40-
return decryptedMessage
60+
let text = utf8Decoder.decode(plaintext)
61+
return text
4162
}
4263

43-
function getNormalizedX(key: Uint8Array): string {
44-
return Buffer.from(key.slice(1, 33)).toString('hex')
64+
function getNormalizedX(key: Uint8Array): Uint8Array {
65+
return key.slice(1, 33)
4566
}

nip19.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as secp256k1 from '@noble/secp256k1'
22
import {bech32} from 'bech32'
33

4+
import {utf8Decoder, utf8Encoder} from './utils'
5+
46
export type ProfilePointer = {
57
pubkey: string // hex
68
relays?: string[]
@@ -11,9 +13,6 @@ export type EventPointer = {
1113
relays?: string[]
1214
}
1315

14-
let utf8Decoder = new TextDecoder('utf-8')
15-
let utf8Encoder = new TextEncoder()
16-
1716
export function decode(nip19: string): {
1817
type: string
1918
data: ProfilePointer | EventPointer | string

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
"@noble/secp256k1": "^1.7.0",
1414
"@scure/bip32": "^1.1.1",
1515
"@scure/bip39": "^1.1.0",
16+
"base64-arraybuffer": "^1.0.2",
1617
"bech32": "^2.0.0",
17-
"browserify-cipher": ">=1",
18-
"buffer": "^6.0.3",
18+
"readable-stream": "^4.2.0",
1919
"websocket-polyfill": "^0.0.3"
2020
},
2121
"keywords": [

utils.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const utf8Decoder = new TextDecoder('utf-8')
2+
export const utf8Encoder = new TextEncoder()

0 commit comments

Comments
 (0)