remove browserify-cipher, use crypto.subtle for nip04.
This commit is contained in:
parent
0500415a4e
commit
41a1614d89
|
@ -24,6 +24,7 @@
|
||||||
"document": false,
|
"document": false,
|
||||||
"navigator": false,
|
"navigator": false,
|
||||||
"window": false,
|
"window": false,
|
||||||
|
"crypto": false,
|
||||||
"location": false,
|
"location": false,
|
||||||
"URL": false,
|
"URL": false,
|
||||||
"URLSearchParams": false,
|
"URLSearchParams": false,
|
||||||
|
|
|
@ -171,7 +171,7 @@ let pk2 = getPublicKey(sk2)
|
||||||
|
|
||||||
// on the sender side
|
// on the sender side
|
||||||
let message = 'hello'
|
let message = 'hello'
|
||||||
let ciphertext = nip04.encrypt(sk1, pk2, 'hello')
|
let ciphertext = await nip04.encrypt(sk1, pk2, 'hello')
|
||||||
|
|
||||||
let event = {
|
let event = {
|
||||||
kind: 4,
|
kind: 4,
|
||||||
|
@ -187,7 +187,7 @@ sendEvent(event)
|
||||||
sub.on('event', (event) => {
|
sub.on('event', (event) => {
|
||||||
let sender = event.tags.find(([k, v]) => k === 'p' && && v && v !== '')[1]
|
let sender = event.tags.find(([k, v]) => k === 'p' && && v && v !== '')[1]
|
||||||
pk1 === sender
|
pk1 === sender
|
||||||
let plaintext = nip04.decrypt(sk2, pk1, event.content)
|
let plaintext = await nip04.decrypt(sk2, pk1, event.content)
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
const {nip04, getPublicKey, generatePrivateKey} = require('./lib/nostr.cjs')
|
const {nip04, getPublicKey, generatePrivateKey} = require('./lib/nostr.cjs')
|
||||||
|
|
||||||
test('encrypt and decrypt message', () => {
|
test('encrypt and decrypt message', async () => {
|
||||||
let sk1 = generatePrivateKey()
|
let sk1 = generatePrivateKey()
|
||||||
let sk2 = generatePrivateKey()
|
let sk2 = generatePrivateKey()
|
||||||
let pk1 = getPublicKey(sk1)
|
let pk1 = getPublicKey(sk1)
|
||||||
let pk2 = getPublicKey(sk2)
|
let pk2 = getPublicKey(sk2)
|
||||||
|
|
||||||
expect(nip04.decrypt(sk2, pk1, nip04.encrypt(sk1, pk2, 'hello'))).toEqual(
|
expect(
|
||||||
'hello'
|
await nip04.decrypt(sk2, pk1, await nip04.encrypt(sk1, pk2, 'hello'))
|
||||||
)
|
).toEqual('hello')
|
||||||
})
|
})
|
||||||
|
|
69
nip04.ts
69
nip04.ts
|
@ -1,45 +1,66 @@
|
||||||
import {Buffer} from 'buffer'
|
|
||||||
import {randomBytes} from '@noble/hashes/utils'
|
import {randomBytes} from '@noble/hashes/utils'
|
||||||
import * as secp256k1 from '@noble/secp256k1'
|
import * as secp256k1 from '@noble/secp256k1'
|
||||||
// @ts-ignore
|
import {encode as b64encode, decode as b64decode} from 'base64-arraybuffer'
|
||||||
import aes from 'browserify-cipher'
|
|
||||||
|
|
||||||
export function encrypt(privkey: string, pubkey: string, text: string): string {
|
import {utf8Decoder, utf8Encoder} from './utils'
|
||||||
|
|
||||||
|
export async function encrypt(
|
||||||
|
privkey: string,
|
||||||
|
pubkey: string,
|
||||||
|
text: string
|
||||||
|
): Promise<string> {
|
||||||
const key = secp256k1.getSharedSecret(privkey, '02' + pubkey)
|
const key = secp256k1.getSharedSecret(privkey, '02' + pubkey)
|
||||||
const normalizedKey = getNormalizedX(key)
|
const normalizedKey = getNormalizedX(key)
|
||||||
|
|
||||||
let iv = Uint8Array.from(randomBytes(16))
|
let iv = Uint8Array.from(randomBytes(16))
|
||||||
var cipher = aes.createCipheriv(
|
let plaintext = utf8Encoder.encode(text)
|
||||||
'aes-256-cbc',
|
let cryptoKey = await crypto.subtle.importKey(
|
||||||
Buffer.from(normalizedKey, 'hex'),
|
'raw',
|
||||||
iv
|
normalizedKey,
|
||||||
|
{name: 'AES-CBC'},
|
||||||
|
false,
|
||||||
|
['encrypt']
|
||||||
)
|
)
|
||||||
let encryptedMessage = cipher.update(text, 'utf8', 'base64')
|
let ciphertext = await crypto.subtle.encrypt(
|
||||||
encryptedMessage += cipher.final('base64')
|
{name: 'AES-CBC', iv},
|
||||||
|
cryptoKey,
|
||||||
|
plaintext
|
||||||
|
)
|
||||||
|
let ctb64 = b64encode(ciphertext)
|
||||||
|
let ivb64 = b64encode(iv.buffer)
|
||||||
|
|
||||||
return `${encryptedMessage}?iv=${Buffer.from(iv.buffer).toString('base64')}`
|
return `${ctb64}?iv=${ivb64}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decrypt(
|
export async function decrypt(
|
||||||
privkey: string,
|
privkey: string,
|
||||||
pubkey: string,
|
pubkey: string,
|
||||||
ciphertext: string
|
data: string
|
||||||
): string {
|
): Promise<string> {
|
||||||
let [cip, iv] = ciphertext.split('?iv=')
|
let [ctb64, ivb64] = data.split('?iv=')
|
||||||
let key = secp256k1.getSharedSecret(privkey, '02' + pubkey)
|
let key = secp256k1.getSharedSecret(privkey, '02' + pubkey)
|
||||||
let normalizedKey = getNormalizedX(key)
|
let normalizedKey = getNormalizedX(key)
|
||||||
|
|
||||||
var decipher = aes.createDecipheriv(
|
let cryptoKey = await crypto.subtle.importKey(
|
||||||
'aes-256-cbc',
|
'raw',
|
||||||
Buffer.from(normalizedKey, 'hex'),
|
normalizedKey,
|
||||||
Buffer.from(iv, 'base64')
|
{name: 'AES-CBC'},
|
||||||
|
false,
|
||||||
|
['decrypt']
|
||||||
)
|
)
|
||||||
let decryptedMessage = decipher.update(cip, 'base64', 'utf8')
|
let ciphertext = b64decode(ctb64)
|
||||||
decryptedMessage += decipher.final('utf8')
|
let iv = b64decode(ivb64)
|
||||||
|
|
||||||
return decryptedMessage
|
let plaintext = await crypto.subtle.decrypt(
|
||||||
|
{name: 'AES-CBC', iv},
|
||||||
|
cryptoKey,
|
||||||
|
ciphertext
|
||||||
|
)
|
||||||
|
|
||||||
|
let text = utf8Decoder.decode(plaintext)
|
||||||
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNormalizedX(key: Uint8Array): string {
|
function getNormalizedX(key: Uint8Array): Uint8Array {
|
||||||
return Buffer.from(key.slice(1, 33)).toString('hex')
|
return key.slice(1, 33)
|
||||||
}
|
}
|
||||||
|
|
5
nip19.ts
5
nip19.ts
|
@ -1,6 +1,8 @@
|
||||||
import * as secp256k1 from '@noble/secp256k1'
|
import * as secp256k1 from '@noble/secp256k1'
|
||||||
import {bech32} from 'bech32'
|
import {bech32} from 'bech32'
|
||||||
|
|
||||||
|
import {utf8Decoder, utf8Encoder} from './utils'
|
||||||
|
|
||||||
export type ProfilePointer = {
|
export type ProfilePointer = {
|
||||||
pubkey: string // hex
|
pubkey: string // hex
|
||||||
relays?: string[]
|
relays?: string[]
|
||||||
|
@ -11,9 +13,6 @@ export type EventPointer = {
|
||||||
relays?: string[]
|
relays?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
let utf8Decoder = new TextDecoder('utf-8')
|
|
||||||
let utf8Encoder = new TextEncoder()
|
|
||||||
|
|
||||||
export function decode(nip19: string): {
|
export function decode(nip19: string): {
|
||||||
type: string
|
type: string
|
||||||
data: ProfilePointer | EventPointer | string
|
data: ProfilePointer | EventPointer | string
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
"@noble/secp256k1": "^1.7.0",
|
"@noble/secp256k1": "^1.7.0",
|
||||||
"@scure/bip32": "^1.1.1",
|
"@scure/bip32": "^1.1.1",
|
||||||
"@scure/bip39": "^1.1.0",
|
"@scure/bip39": "^1.1.0",
|
||||||
|
"base64-arraybuffer": "^1.0.2",
|
||||||
"bech32": "^2.0.0",
|
"bech32": "^2.0.0",
|
||||||
"browserify-cipher": ">=1",
|
"readable-stream": "^4.2.0",
|
||||||
"buffer": "^6.0.3",
|
|
||||||
"websocket-polyfill": "^0.0.3"
|
"websocket-polyfill": "^0.0.3"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|
Loading…
Reference in New Issue