diff options
author | Chocobozzz <me@florianbigard.com> | 2022-10-10 11:12:23 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-10-10 11:12:23 +0200 |
commit | a3e5f804ad821f6979e8735b0569b1209986fedc (patch) | |
tree | 5b34a6bd6b3cb1c5e3eed32a72d02922100d53dc /server/helpers/peertube-crypto.ts | |
parent | a0da6f90d16027b385a67da6a5691b163626a363 (diff) | |
download | PeerTube-a3e5f804ad821f6979e8735b0569b1209986fedc.tar.gz PeerTube-a3e5f804ad821f6979e8735b0569b1209986fedc.tar.zst PeerTube-a3e5f804ad821f6979e8735b0569b1209986fedc.zip |
Encrypt OTP secret
Diffstat (limited to 'server/helpers/peertube-crypto.ts')
-rw-r--r-- | server/helpers/peertube-crypto.ts | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/server/helpers/peertube-crypto.ts b/server/helpers/peertube-crypto.ts index dcf47ce76..ae7d11800 100644 --- a/server/helpers/peertube-crypto.ts +++ b/server/helpers/peertube-crypto.ts | |||
@@ -1,11 +1,11 @@ | |||
1 | import { compare, genSalt, hash } from 'bcrypt' | 1 | import { compare, genSalt, hash } from 'bcrypt' |
2 | import { createSign, createVerify } from 'crypto' | 2 | import { createCipheriv, createDecipheriv, createSign, createVerify } from 'crypto' |
3 | import { Request } from 'express' | 3 | import { Request } from 'express' |
4 | import { cloneDeep } from 'lodash' | 4 | import { cloneDeep } from 'lodash' |
5 | import { sha256 } from '@shared/extra-utils' | 5 | import { sha256 } from '@shared/extra-utils' |
6 | import { BCRYPT_SALT_SIZE, HTTP_SIGNATURE, PRIVATE_RSA_KEY_SIZE } from '../initializers/constants' | 6 | import { BCRYPT_SALT_SIZE, ENCRYPTION, HTTP_SIGNATURE, PRIVATE_RSA_KEY_SIZE } from '../initializers/constants' |
7 | import { MActor } from '../types/models' | 7 | import { MActor } from '../types/models' |
8 | import { generateRSAKeyPairPromise, promisify1, promisify2 } from './core-utils' | 8 | import { generateRSAKeyPairPromise, promisify1, promisify2, randomBytesPromise, scryptPromise } from './core-utils' |
9 | import { jsonld } from './custom-jsonld-signature' | 9 | import { jsonld } from './custom-jsonld-signature' |
10 | import { logger } from './logger' | 10 | import { logger } from './logger' |
11 | 11 | ||
@@ -21,7 +21,9 @@ function createPrivateAndPublicKeys () { | |||
21 | return generateRSAKeyPairPromise(PRIVATE_RSA_KEY_SIZE) | 21 | return generateRSAKeyPairPromise(PRIVATE_RSA_KEY_SIZE) |
22 | } | 22 | } |
23 | 23 | ||
24 | // --------------------------------------------------------------------------- | ||
24 | // User password checks | 25 | // User password checks |
26 | // --------------------------------------------------------------------------- | ||
25 | 27 | ||
26 | function comparePassword (plainPassword: string, hashPassword: string) { | 28 | function comparePassword (plainPassword: string, hashPassword: string) { |
27 | if (!plainPassword) return Promise.resolve(false) | 29 | if (!plainPassword) return Promise.resolve(false) |
@@ -35,7 +37,9 @@ async function cryptPassword (password: string) { | |||
35 | return bcryptHashPromise(password, salt) | 37 | return bcryptHashPromise(password, salt) |
36 | } | 38 | } |
37 | 39 | ||
40 | // --------------------------------------------------------------------------- | ||
38 | // HTTP Signature | 41 | // HTTP Signature |
42 | // --------------------------------------------------------------------------- | ||
39 | 43 | ||
40 | function isHTTPSignatureDigestValid (rawBody: Buffer, req: Request): boolean { | 44 | function isHTTPSignatureDigestValid (rawBody: Buffer, req: Request): boolean { |
41 | if (req.headers[HTTP_SIGNATURE.HEADER_NAME] && req.headers['digest']) { | 45 | if (req.headers[HTTP_SIGNATURE.HEADER_NAME] && req.headers['digest']) { |
@@ -64,7 +68,9 @@ function parseHTTPSignature (req: Request, clockSkew?: number) { | |||
64 | return parsed | 68 | return parsed |
65 | } | 69 | } |
66 | 70 | ||
71 | // --------------------------------------------------------------------------- | ||
67 | // JSONLD | 72 | // JSONLD |
73 | // --------------------------------------------------------------------------- | ||
68 | 74 | ||
69 | function isJsonLDSignatureVerified (fromActor: MActor, signedDocument: any): Promise<boolean> { | 75 | function isJsonLDSignatureVerified (fromActor: MActor, signedDocument: any): Promise<boolean> { |
70 | if (signedDocument.signature.type === 'RsaSignature2017') { | 76 | if (signedDocument.signature.type === 'RsaSignature2017') { |
@@ -114,6 +120,8 @@ async function signJsonLDObject <T> (byActor: MActor, data: T) { | |||
114 | return Object.assign(data, { signature }) | 120 | return Object.assign(data, { signature }) |
115 | } | 121 | } |
116 | 122 | ||
123 | // --------------------------------------------------------------------------- | ||
124 | |||
117 | function buildDigest (body: any) { | 125 | function buildDigest (body: any) { |
118 | const rawBody = typeof body === 'string' ? body : JSON.stringify(body) | 126 | const rawBody = typeof body === 'string' ? body : JSON.stringify(body) |
119 | 127 | ||
@@ -121,6 +129,34 @@ function buildDigest (body: any) { | |||
121 | } | 129 | } |
122 | 130 | ||
123 | // --------------------------------------------------------------------------- | 131 | // --------------------------------------------------------------------------- |
132 | // Encryption | ||
133 | // --------------------------------------------------------------------------- | ||
134 | |||
135 | async function encrypt (str: string, secret: string) { | ||
136 | const iv = await randomBytesPromise(ENCRYPTION.IV) | ||
137 | |||
138 | const key = await scryptPromise(secret, ENCRYPTION.SALT, 32) | ||
139 | const cipher = createCipheriv(ENCRYPTION.ALGORITHM, key, iv) | ||
140 | |||
141 | let encrypted = iv.toString(ENCRYPTION.ENCODING) + ':' | ||
142 | encrypted += cipher.update(str, 'utf8', ENCRYPTION.ENCODING) | ||
143 | encrypted += cipher.final(ENCRYPTION.ENCODING) | ||
144 | |||
145 | return encrypted | ||
146 | } | ||
147 | |||
148 | async function decrypt (encryptedArg: string, secret: string) { | ||
149 | const [ ivStr, encryptedStr ] = encryptedArg.split(':') | ||
150 | |||
151 | const iv = Buffer.from(ivStr, 'hex') | ||
152 | const key = await scryptPromise(secret, ENCRYPTION.SALT, 32) | ||
153 | |||
154 | const decipher = createDecipheriv(ENCRYPTION.ALGORITHM, key, iv) | ||
155 | |||
156 | return decipher.update(encryptedStr, ENCRYPTION.ENCODING, 'utf8') + decipher.final('utf8') | ||
157 | } | ||
158 | |||
159 | // --------------------------------------------------------------------------- | ||
124 | 160 | ||
125 | export { | 161 | export { |
126 | isHTTPSignatureDigestValid, | 162 | isHTTPSignatureDigestValid, |
@@ -131,7 +167,10 @@ export { | |||
131 | comparePassword, | 167 | comparePassword, |
132 | createPrivateAndPublicKeys, | 168 | createPrivateAndPublicKeys, |
133 | cryptPassword, | 169 | cryptPassword, |
134 | signJsonLDObject | 170 | signJsonLDObject, |
171 | |||
172 | encrypt, | ||
173 | decrypt | ||
135 | } | 174 | } |
136 | 175 | ||
137 | // --------------------------------------------------------------------------- | 176 | // --------------------------------------------------------------------------- |