Skip to content

Commit 56a8ccb

Browse files
committed
chore: wip
1 parent 3eedb1c commit 56a8ccb

File tree

16 files changed

+3279
-46
lines changed

16 files changed

+3279
-46
lines changed

packages/aes/README.md

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
<p align="center"><img src="../../.github/art/cover.jpg" alt="Social Card of this repo"></p>
2+
3+
[![npm version][npm-version-src]][npm-version-href]
4+
[![GitHub Actions][github-actions-src]][github-actions-href]
5+
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
6+
<!-- [![npm downloads][npm-downloads-src]][npm-downloads-href] -->
7+
<!-- [![Codecov][codecov-src]][codecov-href] -->
8+
9+
# ts-aes
10+
11+
> A TypeScript implementation of AES encryption and decryption with a focus on type safety and standards compliance.
12+
13+
## Features
14+
15+
- 🔒 **DER Compliant** _Implements ASN.1 encoding & decoding according to standard_
16+
- 🔄 **Comprehensive Type Support** _Support for INTEGER, BIT STRING, OCTET STRING, NULL, OBJECT IDENTIFIER, SEQUENCE, SET, and more_
17+
- 🧩 **Validation** _Validate ASN.1 structures against expected schemas_
18+
- 🔧 **Flexible Parsing** _Support for both strict DER and more lenient BER parsing_
19+
- 🛡️ **Type Safety** _Full TypeScript support with comprehensive type definitions_
20+
- 🪶 **Lightweight** _No dependencies_
21+
- 🔍 **Debugging** _Pretty printing of ASN.1 structures for easier debugging_
22+
23+
## Install
24+
25+
```bash
26+
# bun
27+
bun install ts-asn1
28+
29+
# npm
30+
npm install ts-asn1
31+
32+
# pnpm
33+
pnpm install ts-asn1
34+
```
35+
36+
## Get Started
37+
38+
After installing the package, you can import and use the ASN.1 encoding and decoding functions:
39+
40+
```ts
41+
import { asn1 } from 'ts-asn1'
42+
import { utils } from 'ts-security-utils'
43+
44+
// Create an ASN.1 INTEGER
45+
const intValue = asn1.integerToDer(123)
46+
console.log(utils.bytesToHex(intValue)) // "7b"
47+
48+
// Parse ASN.1 DER encoded data
49+
const derData = utils.hexToBytes('300a02010102010202010304010a')
50+
const asn1Object = asn1.fromDer(derData)
51+
console.log(asn1.prettyPrint(asn1Object))
52+
// SEQUENCE {
53+
// INTEGER 1
54+
// INTEGER 2
55+
// INTEGER 3
56+
// OCTET STRING 0a
57+
// }
58+
59+
// Convert dates to/from ASN.1 generalized time
60+
const date = new Date('2025-03-01T12:00:00Z')
61+
const genTime = asn1.dateToGeneralizedTime(date)
62+
console.log(genTime) // "20250301120000Z"
63+
64+
// Convert back to a date
65+
const parsedDate = asn1.generalizedTimeToDate(genTime)
66+
console.log(parsedDate.toISOString()) // "2025-03-01T12:00:00.000Z"
67+
```
68+
69+
## API Reference
70+
71+
### ASN.1 Types
72+
73+
The library supports all standard ASN.1 types:
74+
75+
```ts
76+
const Type = {
77+
BOOLEAN: 1,
78+
INTEGER: 2,
79+
BITSTRING: 3,
80+
OCTETSTRING: 4,
81+
NULL: 5,
82+
OID: 6,
83+
OBJECT_DESCRIPTOR: 7,
84+
EXTERNAL: 8,
85+
REAL: 9,
86+
ENUMERATED: 10,
87+
EMBEDDED_PDV: 11,
88+
UTF8: 12,
89+
RELATIVE_OID: 13,
90+
SEQUENCE: 16,
91+
SET: 17,
92+
NUMERIC_STRING: 18,
93+
PRINTABLE_STRING: 19,
94+
T61_STRING: 20,
95+
VIDEOTEX_STRING: 21,
96+
IA5_STRING: 22,
97+
UTC_TIME: 23,
98+
GENERALIZED_TIME: 24,
99+
GRAPHIC_STRING: 25,
100+
VISIBLE_STRING: 26,
101+
GENERAL_STRING: 27,
102+
UNIVERSAL_STRING: 28,
103+
CHARACTER_STRING: 29,
104+
BMP_STRING: 30
105+
} as const
106+
```
107+
108+
### ASN.1 Tag Classes
109+
110+
```ts
111+
const Class = {
112+
UNIVERSAL: 0,
113+
APPLICATION: 1,
114+
CONTEXT_SPECIFIC: 2,
115+
PRIVATE: 3
116+
} as const
117+
```
118+
119+
### Key Functions
120+
121+
#### Encoding/Decoding
122+
123+
```ts
124+
// Convert to/from DER encoding
125+
function fromDer(bytes: Uint8Array, options?: FromDerOptions): Asn1Object
126+
function toDer(obj: Asn1Object): Buffer
127+
128+
// Convert integers to/from DER
129+
function integerToDer(n: number): Buffer
130+
function derToInteger(bytes: Uint8Array): number
131+
132+
// Convert OIDs to/from DER
133+
function oidToDer(oid: string): Buffer
134+
function derToOid(bytes: Uint8Array): string
135+
136+
// Date conversions
137+
function dateToGeneralizedTime(date: Date): string
138+
function generalizedTimeToDate(genTime: string): Date
139+
function dateToUtcTime(date: Date): string
140+
function utcTimeToDate(utcTime: string): Date
141+
```
142+
143+
#### Utility Functions
144+
145+
```ts
146+
// Create a copy of an ASN.1 object
147+
function copy(obj: Asn1Object): Asn1Object
148+
149+
// Compare two ASN.1 objects for equality
150+
function equals(obj1: any, obj2: any): boolean
151+
152+
// Validate an ASN.1 object against a schema
153+
function validate(obj: Asn1Object, validator: Validator, capture?: Record<string, any>, errors?: string[]): boolean
154+
155+
// Pretty print an ASN.1 object for debugging
156+
function prettyPrint(obj: Asn1Object, indent?: string): string
157+
```
158+
159+
## Testing
160+
161+
```bash
162+
bun test
163+
```
164+
165+
## Changelog
166+
167+
Please see our [releases](https://github.com/stacksjs/ts-security/releases) page for more information on what has changed recently.
168+
169+
## Contributing
170+
171+
Please review the [Contributing Guide](https://github.com/stacksjs/contributing) for details.
172+
173+
## Community
174+
175+
For help, discussion about best practices, or any other conversation that would benefit from being searchable:
176+
177+
[Discussions on GitHub](https://github.com/stacksjs/stacks/discussions)
178+
179+
For casual chit-chat with others using this package:
180+
181+
[Join the Stacks Discord Server](https://discord.gg/stacksjs)
182+
183+
## Postcardware
184+
185+
"Software that is free, but hopes for a postcard." We love receiving postcards from around the world showing where `ts-asn1` is being used! We showcase them on our website too.
186+
187+
Our address: Stacks.js, 12665 Village Ln #2306, Playa Vista, CA 90094, United States 🌎
188+
189+
## Sponsors
190+
191+
We would like to extend our thanks to the following sponsors for funding Stacks development. If you are interested in becoming a sponsor, please reach out to us.
192+
193+
- [JetBrains](https://www.jetbrains.com/)
194+
- [The Solana Foundation](https://solana.com/)
195+
196+
## Credits
197+
198+
- [Dave Longley](https://github.com/dlongley)
199+
- [node-forge](https://github.com/digitalbazaar/forge)
200+
- [Chris Breuer](https://github.com/chrisbbreuer)
201+
- [All Contributors](../../contributors)
202+
203+
## License
204+
205+
The MIT License (MIT). Please see [LICENSE](https://github.com/stacksjs/stacks/tree/main/LICENSE.md) for more information.
206+
207+
Made with 💙
208+
209+
<!-- Badges -->
210+
[npm-version-src]: https://img.shields.io/npm/v/@stacksjs/ts-asn1?style=flat-square
211+
[npm-version-href]: https://npmjs.com/package/@stacksjs/ts-asn1
212+
[github-actions-src]: https://img.shields.io/github/actions/workflow/status/stacksjs/ts-security/ci.yml?style=flat-square&branch=main
213+
[github-actions-href]: https://github.com/stacksjs/ts-security/actions?query=workflow%3Aci
214+
215+
<!-- [codecov-src]: https://img.shields.io/codecov/c/gh/stacksjs/ts-asn1/main?style=flat-square
216+
[codecov-href]: https://codecov.io/gh/stacksjs/ts-asn1 -->

packages/aes/build.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import process from 'node:process'
2+
import { dts } from 'bun-plugin-dtsx'
3+
4+
console.log('Building...')
5+
6+
const result = await Bun.build({
7+
entrypoints: ['./src/index.ts'],
8+
outdir: './dist',
9+
minify: true,
10+
plugins: [
11+
dts(),
12+
],
13+
})
14+
15+
if (!result.success) {
16+
console.error('Build failed')
17+
18+
for (const message of result.logs) {
19+
// Bun will pretty print the message object
20+
console.error(message)
21+
}
22+
23+
process.exit(1)
24+
}
25+
26+
console.log('Build complete')

packages/aes/package.json

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"name": "ts-asn1",
3+
"type": "module",
4+
"version": "0.0.0",
5+
"description": "A ASN.1 library.",
6+
"author": "Chris Breuer <chris@stacksjs.org> (https://github.com/chrisbbreuer)",
7+
"license": "MIT",
8+
"homepage": "https://github.com/stacksjs/ts-security#readme",
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/stacksjs/ts-security.git"
12+
},
13+
"bugs": {
14+
"url": "https://github.com/stacksjs/ts-security/issues"
15+
},
16+
"keywords": [
17+
"asn1",
18+
"asn.1",
19+
"crypto",
20+
"cryptography",
21+
"bun",
22+
"stacks",
23+
"node-forge",
24+
"typescript",
25+
"javascript"
26+
],
27+
"exports": {
28+
".": {
29+
"types": "./dist/index.d.ts",
30+
"import": "./dist/index.js"
31+
}
32+
},
33+
"module": "./dist/index.js",
34+
"types": "./dist/index.d.ts",
35+
"files": ["README.md", "dist"],
36+
"scripts": {
37+
"build": "bun build.ts",
38+
"lint": "bunx --bun eslint .",
39+
"lint:fix": "bunx --bun eslint . --fix",
40+
"fresh": "bunx rimraf node_modules/ bun.lock && bun i",
41+
"changelog": "bunx changelogen --output CHANGELOG.md",
42+
"prepublishOnly": "bun --bun run build",
43+
"release": "bun run changelog && bunx bumpp package.json --all",
44+
"test": "bun test",
45+
"typecheck": "bun --bun tsc --noEmit"
46+
},
47+
"dependencies": {
48+
"ts-security-utils": "workspace:*"
49+
},
50+
"simple-git-hooks": {
51+
"pre-commit": "bun lint-staged"
52+
},
53+
"lint-staged": {
54+
"*.{js,ts}": "bunx eslint . --fix"
55+
}
56+
}

packages/wip/algorithms/symmetric/aes.ts renamed to packages/aes/src/aes.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import type { Algorithm, BlockCipher } from './cipher'
1919
import type { CipherMode } from './cipher-modes'
20-
import { ByteStringBuffer, createBuffer } from '../../utils'
20+
import { ByteStringBuffer, createBuffer } from 'ts-security-utils'
2121
import { createCipher, registerAlgorithm as registerCipherAlgorithm } from './cipher'
2222
import { modes } from './cipher-modes'
2323

@@ -489,18 +489,18 @@ export function _expandKey(key: number[], decrypt: boolean): number[] {
489489
// temp = SubWord(RotWord(temp)) ^ Rcon[i / Nk]
490490
temp
491491
= sbox[temp >>> 16 & 255] << 24
492-
^ sbox[temp >>> 8 & 255] << 16
493-
^ sbox[temp & 255] << 8
494-
^ sbox[temp >>> 24] ^ (rcon[iNk] << 24)
492+
^ sbox[temp >>> 8 & 255] << 16
493+
^ sbox[temp & 255] << 8
494+
^ sbox[temp >>> 24] ^ (rcon[iNk] << 24)
495495
iNk++
496496
}
497497
else if (Nk > 6 && (i % Nk === 4)) {
498498
// temp = SubWord(temp)
499499
temp
500500
= sbox[temp >>> 24] << 24
501-
^ sbox[temp >>> 16 & 255] << 16
502-
^ sbox[temp >>> 8 & 255] << 8
503-
^ sbox[temp & 255]
501+
^ sbox[temp >>> 16 & 255] << 16
502+
^ sbox[temp >>> 8 & 255] << 8
503+
^ sbox[temp & 255]
504504
}
505505
w[i] = w[i - Nk] ^ temp
506506
}
@@ -820,24 +820,24 @@ export function _updateBlock(w: number[], input: number[], output: number[], dec
820820
// Note: rows are shifted inline
821821
output[0]
822822
= (sub[a >>> 24] << 24)
823-
^ (sub[b >>> 16 & 255] << 16)
824-
^ (sub[c >>> 8 & 255] << 8)
825-
^ (sub[d & 255]) ^ w[++i]
823+
^ (sub[b >>> 16 & 255] << 16)
824+
^ (sub[c >>> 8 & 255] << 8)
825+
^ (sub[d & 255]) ^ w[++i]
826826
output[decrypt ? 3 : 1]
827827
= (sub[b >>> 24] << 24)
828-
^ (sub[c >>> 16 & 255] << 16)
829-
^ (sub[d >>> 8 & 255] << 8)
830-
^ (sub[a & 255]) ^ w[++i]
828+
^ (sub[c >>> 16 & 255] << 16)
829+
^ (sub[d >>> 8 & 255] << 8)
830+
^ (sub[a & 255]) ^ w[++i]
831831
output[2]
832832
= (sub[c >>> 24] << 24)
833-
^ (sub[d >>> 16 & 255] << 16)
834-
^ (sub[a >>> 8 & 255] << 8)
835-
^ (sub[b & 255]) ^ w[++i]
833+
^ (sub[d >>> 16 & 255] << 16)
834+
^ (sub[a >>> 8 & 255] << 8)
835+
^ (sub[b & 255]) ^ w[++i]
836836
output[decrypt ? 1 : 3]
837837
= (sub[d >>> 24] << 24)
838-
^ (sub[a >>> 16 & 255] << 16)
839-
^ (sub[b >>> 8 & 255] << 8)
840-
^ (sub[c & 255]) ^ w[++i]
838+
^ (sub[a >>> 16 & 255] << 16)
839+
^ (sub[b >>> 8 & 255] << 8)
840+
^ (sub[c & 255]) ^ w[++i]
841841
}
842842

843843
function createEncryptionCipher(key: string, bits: string | Buffer): BlockCipher {

0 commit comments

Comments
 (0)