@l1yp/file-viewer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +134 -0
- package/dist/FileViewer.js +7 -0
- package/dist/FileViewer.vue.d.ts +37 -0
- package/dist/FileViewer.vue_vue_type_script_setup_true_lang.js +103 -0
- package/dist/_virtual/_plugin-vue_export-helper.js +8 -0
- package/dist/components/AppxViewer.js +7 -0
- package/dist/components/AppxViewer.vue.d.ts +18 -0
- package/dist/components/AppxViewer.vue_vue_type_script_setup_true_lang.js +174 -0
- package/dist/components/ArchiveBrowser.js +7 -0
- package/dist/components/ArchiveBrowser.vue.d.ts +18 -0
- package/dist/components/ArchiveBrowser.vue_vue_type_script_setup_true_lang.js +279 -0
- package/dist/components/AudioViewer.js +7 -0
- package/dist/components/AudioViewer.vue.d.ts +21 -0
- package/dist/components/AudioViewer.vue_vue_type_script_setup_true_lang.js +201 -0
- package/dist/components/BinObjBrowser.js +7 -0
- package/dist/components/BinObjBrowser.vue.d.ts +19 -0
- package/dist/components/BinObjBrowser.vue_vue_type_script_setup_true_lang.js +141 -0
- package/dist/components/CertViewer.js +7 -0
- package/dist/components/CertViewer.vue.d.ts +17 -0
- package/dist/components/CertViewer.vue_vue_type_script_setup_true_lang.js +251 -0
- package/dist/components/ClassViewer.js +7 -0
- package/dist/components/ClassViewer.vue.d.ts +15 -0
- package/dist/components/ClassViewer.vue_vue_type_script_setup_true_lang.js +164 -0
- package/dist/components/CodeBlock.js +7 -0
- package/dist/components/CodeBlock.vue.d.ts +17 -0
- package/dist/components/CodeBlock.vue_vue_type_script_setup_true_lang.js +79 -0
- package/dist/components/CodeView.js +7 -0
- package/dist/components/CodeView.vue.d.ts +21 -0
- package/dist/components/CodeView.vue_vue_type_script_setup_true_lang.js +180 -0
- package/dist/components/CsvViewer.js +7 -0
- package/dist/components/CsvViewer.vue.d.ts +26 -0
- package/dist/components/CsvViewer.vue_vue_type_script_setup_true_lang.js +187 -0
- package/dist/components/DicomViewer.js +7 -0
- package/dist/components/DicomViewer.vue.d.ts +30 -0
- package/dist/components/DicomViewer.vue_vue_type_script_setup_true_lang.js +362 -0
- package/dist/components/DocxViewer.js +7 -0
- package/dist/components/DocxViewer.vue.d.ts +19 -0
- package/dist/components/DocxViewer.vue_vue_type_script_setup_true_lang.js +59 -0
- package/dist/components/DrawioViewer.js +7 -0
- package/dist/components/DrawioViewer.vue.d.ts +16 -0
- package/dist/components/DrawioViewer.vue_vue_type_script_setup_true_lang.js +38 -0
- package/dist/components/DxfViewer.js +7 -0
- package/dist/components/DxfViewer.vue.d.ts +14 -0
- package/dist/components/DxfViewer.vue_vue_type_script_setup_true_lang.js +239 -0
- package/dist/components/EbookViewer.js +7 -0
- package/dist/components/EbookViewer.vue.d.ts +22 -0
- package/dist/components/EbookViewer.vue_vue_type_script_setup_true_lang.js +170 -0
- package/dist/components/EmlViewer.js +7 -0
- package/dist/components/EmlViewer.vue.d.ts +21 -0
- package/dist/components/EmlViewer.vue_vue_type_script_setup_true_lang.js +193 -0
- package/dist/components/EplViewer.js +7 -0
- package/dist/components/EplViewer.vue.d.ts +19 -0
- package/dist/components/EplViewer.vue_vue_type_script_setup_true_lang.js +201 -0
- package/dist/components/FileViewerBody.js +7 -0
- package/dist/components/FileViewerBody.vue.d.ts +47 -0
- package/dist/components/FileViewerBody.vue_vue_type_script_setup_true_lang.js +599 -0
- package/dist/components/FileViewerPanel.js +7 -0
- package/dist/components/FileViewerPanel.vue.d.ts +3 -0
- package/dist/components/FileViewerPanel.vue_vue_type_script_setup_true_lang.js +207 -0
- package/dist/components/FontViewer.js +7 -0
- package/dist/components/FontViewer.vue.d.ts +17 -0
- package/dist/components/FontViewer.vue_vue_type_script_setup_true_lang.js +120 -0
- package/dist/components/FrontmatterCard.js +7 -0
- package/dist/components/FrontmatterCard.vue.d.ts +11 -0
- package/dist/components/FrontmatterCard.vue_vue_type_script_setup_true_lang.js +30 -0
- package/dist/components/GeoViewer.js +7 -0
- package/dist/components/GeoViewer.vue.d.ts +17 -0
- package/dist/components/GeoViewer.vue_vue_type_script_setup_true_lang.js +255 -0
- package/dist/components/HarViewer.js +7 -0
- package/dist/components/HarViewer.vue.d.ts +20 -0
- package/dist/components/HarViewer.vue_vue_type_script_setup_true_lang.js +322 -0
- package/dist/components/HexViewer.js +7 -0
- package/dist/components/HexViewer.vue.d.ts +22 -0
- package/dist/components/HexViewer.vue_vue_type_script_setup_true_lang.js +121 -0
- package/dist/components/HprofViewer.js +7 -0
- package/dist/components/HprofViewer.vue.d.ts +27 -0
- package/dist/components/HprofViewer.vue_vue_type_script_setup_true_lang.js +561 -0
- package/dist/components/ImageLightbox.js +7 -0
- package/dist/components/ImageLightbox.vue.d.ts +3 -0
- package/dist/components/ImageLightbox.vue_vue_type_script_setup_true_lang.js +86 -0
- package/dist/components/InlineText.d.ts +29 -0
- package/dist/components/InlineText.js +21 -0
- package/dist/components/JksViewer.js +7 -0
- package/dist/components/JksViewer.vue.d.ts +22 -0
- package/dist/components/JksViewer.vue_vue_type_script_setup_true_lang.js +353 -0
- package/dist/components/JsonlViewer.js +7 -0
- package/dist/components/JsonlViewer.vue.d.ts +15 -0
- package/dist/components/JsonlViewer.vue_vue_type_script_setup_true_lang.js +103 -0
- package/dist/components/LogViewer.js +7 -0
- package/dist/components/LogViewer.vue.d.ts +29 -0
- package/dist/components/LogViewer.vue_vue_type_script_setup_true_lang.js +670 -0
- package/dist/components/LrcViewer.js +7 -0
- package/dist/components/LrcViewer.vue.d.ts +17 -0
- package/dist/components/LrcViewer.vue_vue_type_script_setup_true_lang.js +106 -0
- package/dist/components/MarkdownTable.js +7 -0
- package/dist/components/MarkdownTable.vue.d.ts +19 -0
- package/dist/components/MarkdownTable.vue_vue_type_script_setup_true_lang.js +71 -0
- package/dist/components/MarkdownText.d.ts +30 -0
- package/dist/components/MarkdownText.js +21 -0
- package/dist/components/MhtViewer.js +7 -0
- package/dist/components/MhtViewer.vue.d.ts +22 -0
- package/dist/components/MhtViewer.vue_vue_type_script_setup_true_lang.js +112 -0
- package/dist/components/MindMapView.js +7 -0
- package/dist/components/MindMapView.vue.d.ts +23 -0
- package/dist/components/MindMapView.vue_vue_type_script_setup_true_lang.js +337 -0
- package/dist/components/MissingDependency.js +7 -0
- package/dist/components/MissingDependency.vue.d.ts +17 -0
- package/dist/components/MissingDependency.vue_vue_type_script_setup_true_lang.js +37 -0
- package/dist/components/ModelViewer.js +7 -0
- package/dist/components/ModelViewer.vue.d.ts +18 -0
- package/dist/components/ModelViewer.vue_vue_type_script_setup_true_lang.js +157 -0
- package/dist/components/MsiViewer.js +7 -0
- package/dist/components/MsiViewer.vue.d.ts +19 -0
- package/dist/components/MsiViewer.vue_vue_type_script_setup_true_lang.js +136 -0
- package/dist/components/NotebookViewer.js +7 -0
- package/dist/components/NotebookViewer.vue.d.ts +20 -0
- package/dist/components/NotebookViewer.vue_vue_type_script_setup_true_lang.js +125 -0
- package/dist/components/PdfViewer.js +7 -0
- package/dist/components/PdfViewer.vue.d.ts +19 -0
- package/dist/components/PdfViewer.vue_vue_type_script_setup_true_lang.js +114 -0
- package/dist/components/PptxViewer.js +7 -0
- package/dist/components/PptxViewer.vue.d.ts +20 -0
- package/dist/components/PptxViewer.vue_vue_type_script_setup_true_lang.js +73 -0
- package/dist/components/PsdViewer.js +7 -0
- package/dist/components/PsdViewer.vue.d.ts +15 -0
- package/dist/components/PsdViewer.vue_vue_type_script_setup_true_lang.js +218 -0
- package/dist/components/QmcAudioViewer.js +7 -0
- package/dist/components/QmcAudioViewer.vue.d.ts +18 -0
- package/dist/components/QmcAudioViewer.vue_vue_type_script_setup_true_lang.js +92 -0
- package/dist/components/RasterViewer.js +7 -0
- package/dist/components/RasterViewer.vue.d.ts +21 -0
- package/dist/components/RasterViewer.vue_vue_type_script_setup_true_lang.js +161 -0
- package/dist/components/RtfViewer.js +7 -0
- package/dist/components/RtfViewer.vue.d.ts +21 -0
- package/dist/components/RtfViewer.vue_vue_type_script_setup_true_lang.js +66 -0
- package/dist/components/SevenZipBrowser.js +7 -0
- package/dist/components/SevenZipBrowser.vue.d.ts +13 -0
- package/dist/components/SevenZipBrowser.vue_vue_type_script_setup_true_lang.js +366 -0
- package/dist/components/SqliteViewer.js +7 -0
- package/dist/components/SqliteViewer.vue.d.ts +18 -0
- package/dist/components/SqliteViewer.vue_vue_type_script_setup_true_lang.js +186 -0
- package/dist/components/SubtitleViewer.js +7 -0
- package/dist/components/SubtitleViewer.vue.d.ts +15 -0
- package/dist/components/SubtitleViewer.vue_vue_type_script_setup_true_lang.js +48 -0
- package/dist/components/XlsxChart.js +7 -0
- package/dist/components/XlsxChart.vue.d.ts +14 -0
- package/dist/components/XlsxChart.vue_vue_type_script_setup_true_lang.js +240 -0
- package/dist/components/XlsxViewer.js +7 -0
- package/dist/components/XlsxViewer.vue.d.ts +22 -0
- package/dist/components/XlsxViewer.vue_vue_type_script_setup_true_lang.js +814 -0
- package/dist/components/XmindViewer.js +7 -0
- package/dist/components/XmindViewer.vue.d.ts +13 -0
- package/dist/components/XmindViewer.vue_vue_type_script_setup_true_lang.js +48 -0
- package/dist/components/ZipBrowser.js +7 -0
- package/dist/components/ZipBrowser.vue.d.ts +14 -0
- package/dist/components/ZipBrowser.vue_vue_type_script_setup_true_lang.js +326 -0
- package/dist/components/ZoomImage.js +7 -0
- package/dist/components/ZoomImage.vue.d.ts +29 -0
- package/dist/components/ZoomImage.vue_vue_type_script_setup_true_lang.js +147 -0
- package/dist/components/epl/EplCodeBlock.js +7 -0
- package/dist/components/epl/EplCodeBlock.vue.d.ts +15 -0
- package/dist/components/epl/EplCodeBlock.vue_vue_type_script_setup_true_lang.js +72 -0
- package/dist/components/epl/EplDoc.js +7 -0
- package/dist/components/epl/EplDoc.vue.d.ts +19 -0
- package/dist/components/epl/EplDoc.vue_vue_type_script_setup_true_lang.js +327 -0
- package/dist/components/epl/EplMethod.js +7 -0
- package/dist/components/epl/EplMethod.vue.d.ts +14 -0
- package/dist/components/epl/EplMethod.vue_vue_type_script_setup_true_lang.js +100 -0
- package/dist/components/epl/EplResource.js +7 -0
- package/dist/components/epl/EplResource.vue.d.ts +15 -0
- package/dist/components/epl/EplResource.vue_vue_type_script_setup_true_lang.js +204 -0
- package/dist/components/epl/EplTree.js +7 -0
- package/dist/components/epl/EplTree.vue.d.ts +27 -0
- package/dist/components/epl/EplTree.vue_vue_type_script_setup_true_lang.js +123 -0
- package/dist/components/epl/EplVarTable.js +7 -0
- package/dist/components/epl/EplVarTable.vue.d.ts +21 -0
- package/dist/components/epl/EplVarTable.vue_vue_type_script_setup_true_lang.js +60 -0
- package/dist/components/epl/docTypes.d.ts +12 -0
- package/dist/components/epl/numbering.d.ts +21 -0
- package/dist/components/epl/numbering.js +14 -0
- package/dist/components/icons/Icon.js +7 -0
- package/dist/components/icons/Icon.vue.d.ts +14 -0
- package/dist/components/icons/Icon.vue_vue_type_script_setup_true_lang.js +33 -0
- package/dist/components/icons/iconPaths.d.ts +60 -0
- package/dist/components/icons/iconPaths.js +54 -0
- package/dist/components/optionalViewer.d.ts +14 -0
- package/dist/components/optionalViewer.js +37 -0
- package/dist/components/ui/ClampBlock.d.ts +82 -0
- package/dist/components/ui/ClampBlock.js +63 -0
- package/dist/composables/useFileViewer.d.ts +428 -0
- package/dist/composables/useFileViewer.js +27 -0
- package/dist/composables/useLightbox.d.ts +33 -0
- package/dist/composables/useLightbox.js +17 -0
- package/dist/composables/useLogRules.d.ts +47 -0
- package/dist/composables/useLogRules.js +74 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +30 -0
- package/dist/lib/aes.d.ts +25 -0
- package/dist/lib/aes.js +99 -0
- package/dist/lib/appx.d.ts +66 -0
- package/dist/lib/appx.js +112 -0
- package/dist/lib/archive.d.ts +29 -0
- package/dist/lib/asn1.d.ts +47 -0
- package/dist/lib/asn1.js +122 -0
- package/dist/lib/binobj.d.ts +69 -0
- package/dist/lib/binobj.js +430 -0
- package/dist/lib/brotli.d.ts +14 -0
- package/dist/lib/brotli.js +16 -0
- package/dist/lib/bzip2.d.ts +14 -0
- package/dist/lib/bzip2.js +161 -0
- package/dist/lib/classfile.d.ts +72 -0
- package/dist/lib/classfile.js +210 -0
- package/dist/lib/codePreview.d.ts +22 -0
- package/dist/lib/codePreview.js +27 -0
- package/dist/lib/codefold.d.ts +14 -0
- package/dist/lib/codefold.js +30 -0
- package/dist/lib/codeformat.d.ts +21 -0
- package/dist/lib/codeformat.js +130 -0
- package/dist/lib/csv.d.ts +19 -0
- package/dist/lib/csv.js +74 -0
- package/dist/lib/des.d.ts +17 -0
- package/dist/lib/des.js +928 -0
- package/dist/lib/diagram.d.ts +5 -0
- package/dist/lib/diagram.js +479 -0
- package/dist/lib/dicom.d.ts +69 -0
- package/dist/lib/dicom.js +442 -0
- package/dist/lib/dicomCodecs.d.ts +28 -0
- package/dist/lib/dicomCodecs.js +156 -0
- package/dist/lib/dicomRender.d.ts +46 -0
- package/dist/lib/dicomRender.js +114 -0
- package/dist/lib/dxf.d.ts +86 -0
- package/dist/lib/dxf.js +399 -0
- package/dist/lib/eml.d.ts +40 -0
- package/dist/lib/eml.js +46 -0
- package/dist/lib/encoding.d.ts +28 -0
- package/dist/lib/encoding.js +44 -0
- package/dist/lib/epl/code/ast.d.ts +150 -0
- package/dist/lib/epl/code/codeDataParser.d.ts +3 -0
- package/dist/lib/epl/code/codeDataParser.js +330 -0
- package/dist/lib/epl/code/codeLines.d.ts +20 -0
- package/dist/lib/epl/code/codeLines.js +191 -0
- package/dist/lib/epl/code/structures.d.ts +86 -0
- package/dist/lib/epl/code/textCode.d.ts +29 -0
- package/dist/lib/epl/code/textCode.js +150 -0
- package/dist/lib/epl/code/variable.d.ts +25 -0
- package/dist/lib/epl/eplDocument.d.ts +21 -0
- package/dist/lib/epl/eplDocument.js +36 -0
- package/dist/lib/epl/imageList.d.ts +28 -0
- package/dist/lib/epl/imageList.js +66 -0
- package/dist/lib/epl/index.d.ts +53 -0
- package/dist/lib/epl/index.js +45 -0
- package/dist/lib/epl/io/binaryReader.d.ts +56 -0
- package/dist/lib/epl/io/binaryReader.js +119 -0
- package/dist/lib/epl/io/encoding.d.ts +16 -0
- package/dist/lib/epl/io/encoding.js +27 -0
- package/dist/lib/epl/model/eplSystemId.d.ts +64 -0
- package/dist/lib/epl/model/eplSystemId.js +16 -0
- package/dist/lib/epl/model/section.d.ts +46 -0
- package/dist/lib/epl/names/eplLibData.js +39 -0
- package/dist/lib/epl/names/idToNameMap.d.ts +33 -0
- package/dist/lib/epl/names/idToNameMap.js +130 -0
- package/dist/lib/epl/names/libNameProvider.d.ts +15 -0
- package/dist/lib/epl/names/libNameProvider.js +18 -0
- package/dist/lib/epl/program.d.ts +120 -0
- package/dist/lib/epl/program.js +134 -0
- package/dist/lib/epl/projectFileReader.d.ts +23 -0
- package/dist/lib/epl/projectFileReader.js +65 -0
- package/dist/lib/epl/sections/code.d.ts +20 -0
- package/dist/lib/epl/sections/esystemInfo.d.ts +14 -0
- package/dist/lib/epl/sections/losable.d.ts +11 -0
- package/dist/lib/epl/sections/projectConfig.d.ts +23 -0
- package/dist/lib/epl/sections/resource.d.ts +57 -0
- package/dist/lib/fb2.d.ts +14 -0
- package/dist/lib/fb2.js +62 -0
- package/dist/lib/fileType.d.ts +315 -0
- package/dist/lib/fileType.js +800 -0
- package/dist/lib/fonts.d.ts +8 -0
- package/dist/lib/fonts.js +4 -0
- package/dist/lib/format.d.ts +16 -0
- package/dist/lib/format.js +38 -0
- package/dist/lib/frontmatter.d.ts +13 -0
- package/dist/lib/frontmatter.js +23 -0
- package/dist/lib/geo.d.ts +30 -0
- package/dist/lib/geo.js +235 -0
- package/dist/lib/har.d.ts +171 -0
- package/dist/lib/har.js +397 -0
- package/dist/lib/highlight.d.ts +18 -0
- package/dist/lib/highlight.js +34 -0
- package/dist/lib/highlightLangs.d.ts +15 -0
- package/dist/lib/highlightLangs.js +93 -0
- package/dist/lib/hprof.d.ts +211 -0
- package/dist/lib/hprof.js +709 -0
- package/dist/lib/ipynb.d.ts +48 -0
- package/dist/lib/ipynb.js +130 -0
- package/dist/lib/jks.d.ts +86 -0
- package/dist/lib/jks.js +167 -0
- package/dist/lib/jsonl.d.ts +29 -0
- package/dist/lib/jsonl.js +24 -0
- package/dist/lib/lrc.d.ts +32 -0
- package/dist/lib/lrc.js +84 -0
- package/dist/lib/lzma.d.ts +70 -0
- package/dist/lib/lzma.js +204 -0
- package/dist/lib/markdown/blocks.d.ts +9 -0
- package/dist/lib/markdown/blocks.js +221 -0
- package/dist/lib/markdown/index.d.ts +3 -0
- package/dist/lib/markdown/inline.d.ts +33 -0
- package/dist/lib/markdown/inline.js +84 -0
- package/dist/lib/markdown/math.d.ts +5 -0
- package/dist/lib/markdown/math.js +25 -0
- package/dist/lib/markdown/segmentize.d.ts +11 -0
- package/dist/lib/markdown/segmentize.js +28 -0
- package/dist/lib/markdown/styles.d.ts +26 -0
- package/dist/lib/markdown/styles.js +135 -0
- package/dist/lib/mht.d.ts +51 -0
- package/dist/lib/mht.js +122 -0
- package/dist/lib/midi.d.ts +28 -0
- package/dist/lib/midi.js +84 -0
- package/dist/lib/mime.d.ts +82 -0
- package/dist/lib/mime.js +151 -0
- package/dist/lib/mindmap.d.ts +51 -0
- package/dist/lib/mindmap.js +113 -0
- package/dist/lib/mobi.d.ts +15 -0
- package/dist/lib/mobi.js +68 -0
- package/dist/lib/msi.d.ts +50 -0
- package/dist/lib/msi.js +332 -0
- package/dist/lib/optionalDep.d.ts +26 -0
- package/dist/lib/optionalDep.js +20 -0
- package/dist/lib/pkcs12.d.ts +56 -0
- package/dist/lib/pkcs12.js +356 -0
- package/dist/lib/qmc.d.ts +50 -0
- package/dist/lib/qmc.js +213 -0
- package/dist/lib/rar.d.ts +16 -0
- package/dist/lib/rar.js +40 -0
- package/dist/lib/rawPreview.d.ts +12 -0
- package/dist/lib/rawPreview.js +54 -0
- package/dist/lib/rc2.d.ts +12 -0
- package/dist/lib/rc2.js +298 -0
- package/dist/lib/resolveInput.d.ts +22 -0
- package/dist/lib/resolveInput.js +55 -0
- package/dist/lib/rtf.d.ts +53 -0
- package/dist/lib/rtf.js +413 -0
- package/dist/lib/sevenZip.d.ts +82 -0
- package/dist/lib/sevenZip.js +395 -0
- package/dist/lib/sha1.d.ts +24 -0
- package/dist/lib/sha1.js +53 -0
- package/dist/lib/sha256.d.ts +21 -0
- package/dist/lib/sha256.js +119 -0
- package/dist/lib/speechAudio.d.ts +36 -0
- package/dist/lib/speechAudio.js +85 -0
- package/dist/lib/sqlite.d.ts +38 -0
- package/dist/lib/sqlite.js +104 -0
- package/dist/lib/subtitle.d.ts +26 -0
- package/dist/lib/subtitle.js +99 -0
- package/dist/lib/tarball.d.ts +20 -0
- package/dist/lib/tarball.js +248 -0
- package/dist/lib/viewerFormats.d.ts +35 -0
- package/dist/lib/viewerFormats.js +83 -0
- package/dist/lib/viewerKind.d.ts +36 -0
- package/dist/lib/viewerKind.js +233 -0
- package/dist/lib/x509.d.ts +68 -0
- package/dist/lib/x509.js +267 -0
- package/dist/lib/xlsx.d.ts +55 -0
- package/dist/lib/xlsx.js +321 -0
- package/dist/lib/xlsxCharts.d.ts +34 -0
- package/dist/lib/xlsxCharts.js +152 -0
- package/dist/lib/xmind.d.ts +6 -0
- package/dist/lib/xmind.js +124 -0
- package/dist/lib/zip.d.ts +56 -0
- package/dist/lib/zip.js +169 -0
- package/dist/style.css +2 -0
- package/dist/types.d.ts +42 -0
- package/package.json +128 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zero-dependency PKCS#12 (PFX) reader — for the keystore viewer (JksViewer.vue), so `.p12`/`.pfx` and the very
|
|
3
|
+
* common `.jks`-that-is-actually-PKCS#12 (keytool defaults to PKCS12 since JDK 9) open with their certificates
|
|
4
|
+
* and private keys instead of just an opaque blob.
|
|
5
|
+
*
|
|
6
|
+
* PKCS#12 (RFC 7292) is a PKCS#7 container whose bags are ALL encrypted (unlike JKS, where certs are plaintext),
|
|
7
|
+
* so nothing shows without the password. This module parses the PFX / AuthenticatedSafe / SafeBag structure,
|
|
8
|
+
* verifies the integrity MAC (which doubles as the password check), and decrypts the bags:
|
|
9
|
+
* - legacy PBE1 (PKCS#12 KDF, SHA-1): `pbeWithSHA1And3-KeyTripleDES` (3DES, see lib/des.ts),
|
|
10
|
+
* `pbeWithSHA1And{40,128}BitRC2` (RC2, see lib/rc2.ts), and the RC4 variants;
|
|
11
|
+
* - modern PBES2: PBKDF2 (HMAC-SHA1/SHA256) + AES-CBC (see lib/aes.ts) or 3DES.
|
|
12
|
+
* The MAC digest supports SHA-1 / SHA-256. Anything outside this set is reported (not decrypted) rather than
|
|
13
|
+
* failing the whole file. READ-ONLY: no signature/trust verification. WebCrypto ships no 3DES/RC2, hence the
|
|
14
|
+
* hand-rolled ciphers.
|
|
15
|
+
*/
|
|
16
|
+
export interface P12Cert {
|
|
17
|
+
der: Uint8Array;
|
|
18
|
+
friendlyName?: string;
|
|
19
|
+
localKeyId?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface P12Key {
|
|
22
|
+
pkcs8: Uint8Array;
|
|
23
|
+
algorithm: string;
|
|
24
|
+
bits?: number;
|
|
25
|
+
curve?: string;
|
|
26
|
+
friendlyName?: string;
|
|
27
|
+
localKeyId?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface Pkcs12Result {
|
|
30
|
+
macPresent: boolean;
|
|
31
|
+
/** true = MAC verified (password correct); false→never returned (becomes wrong-password); null = no/unsupported MAC. */
|
|
32
|
+
macVerified: boolean | null;
|
|
33
|
+
macAlgorithm?: string;
|
|
34
|
+
certs: P12Cert[];
|
|
35
|
+
keys: P12Key[];
|
|
36
|
+
/** Human names of the PBE algorithms encountered (for display). */
|
|
37
|
+
encryptionAlgos: string[];
|
|
38
|
+
/** Non-fatal notes (e.g. a bag encrypted with an unsupported algorithm was skipped). */
|
|
39
|
+
warnings: string[];
|
|
40
|
+
}
|
|
41
|
+
export type Pkcs12Open = {
|
|
42
|
+
ok: true;
|
|
43
|
+
result: Pkcs12Result;
|
|
44
|
+
} | {
|
|
45
|
+
ok: false;
|
|
46
|
+
reason: 'wrong-password' | 'unsupported' | 'malformed';
|
|
47
|
+
detail?: string;
|
|
48
|
+
};
|
|
49
|
+
/** Does this look like a PKCS#12 PFX (SEQUENCE { version 3, ContentInfo … })? Cheap structural sniff. */
|
|
50
|
+
export declare function looksLikePkcs12(bytes: Uint8Array): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Parse + decrypt a PKCS#12 keystore with `password`. Certificates and private keys come back decrypted; the
|
|
53
|
+
* MAC (when SHA-1/SHA-256) is verified and doubles as the password check. Returns a structured error for a
|
|
54
|
+
* wrong password / unsupported algorithm / malformed file rather than throwing.
|
|
55
|
+
*/
|
|
56
|
+
export declare function readPkcs12(buf: ArrayBuffer, password: string): Pkcs12Open;
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { aesCbcDecrypt as e } from "./aes.js";
|
|
2
|
+
import { Sha1 as t } from "./sha1.js";
|
|
3
|
+
import { TAG as n, decodeAsn1 as r, oidToString as i } from "./asn1.js";
|
|
4
|
+
import { describePrivateKey as a } from "./x509.js";
|
|
5
|
+
import { sha256 as o } from "./sha256.js";
|
|
6
|
+
import { tripleDesCbcDecrypt as s } from "./des.js";
|
|
7
|
+
import { rc2CbcDecrypt as c } from "./rc2.js";
|
|
8
|
+
//#region src/lib/pkcs12.ts
|
|
9
|
+
var l = "1.2.840.113549.1.7.1", u = "1.2.840.113549.1.7.2", d = "1.2.840.113549.1.7.6", f = "1.2.840.113549.1.12.10.1.3", p = "1.2.840.113549.1.12.10.1.1", m = "1.2.840.113549.1.12.10.1.2", h = "1.2.840.113549.1.9.22.1", g = "1.2.840.113549.1.9.20", _ = "1.2.840.113549.1.9.21", v = "1.2.840.113549.1.5.13", y = "1.2.840.113549.1.5.12", b = "1.2.840.113549.3.7", x = "1.2.840.113549.2.7", S = "1.2.840.113549.2.9", C = "1.3.14.3.2.26", w = "2.16.840.1.101.3.4.2.1", T = {
|
|
10
|
+
"2.16.840.1.101.3.4.1.2": 16,
|
|
11
|
+
"2.16.840.1.101.3.4.1.22": 24,
|
|
12
|
+
"2.16.840.1.101.3.4.1.42": 32
|
|
13
|
+
}, E = {
|
|
14
|
+
"1.2.840.113549.1.12.1.1": {
|
|
15
|
+
keyLen: 16,
|
|
16
|
+
ivLen: 0,
|
|
17
|
+
cipher: "rc4"
|
|
18
|
+
},
|
|
19
|
+
"1.2.840.113549.1.12.1.2": {
|
|
20
|
+
keyLen: 5,
|
|
21
|
+
ivLen: 0,
|
|
22
|
+
cipher: "rc4"
|
|
23
|
+
},
|
|
24
|
+
"1.2.840.113549.1.12.1.3": {
|
|
25
|
+
keyLen: 24,
|
|
26
|
+
ivLen: 8,
|
|
27
|
+
cipher: "3des"
|
|
28
|
+
},
|
|
29
|
+
"1.2.840.113549.1.12.1.4": {
|
|
30
|
+
keyLen: 16,
|
|
31
|
+
ivLen: 8,
|
|
32
|
+
cipher: "3des"
|
|
33
|
+
},
|
|
34
|
+
"1.2.840.113549.1.12.1.5": {
|
|
35
|
+
keyLen: 16,
|
|
36
|
+
ivLen: 8,
|
|
37
|
+
effBits: 128,
|
|
38
|
+
cipher: "rc2"
|
|
39
|
+
},
|
|
40
|
+
"1.2.840.113549.1.12.1.6": {
|
|
41
|
+
keyLen: 5,
|
|
42
|
+
ivLen: 8,
|
|
43
|
+
effBits: 40,
|
|
44
|
+
cipher: "rc2"
|
|
45
|
+
}
|
|
46
|
+
}, D = {
|
|
47
|
+
"1.2.840.113549.1.12.1.1": "PBE-SHA1-RC4-128",
|
|
48
|
+
"1.2.840.113549.1.12.1.2": "PBE-SHA1-RC4-40",
|
|
49
|
+
"1.2.840.113549.1.12.1.3": "PBE-SHA1-3DES",
|
|
50
|
+
"1.2.840.113549.1.12.1.4": "PBE-SHA1-2DES",
|
|
51
|
+
"1.2.840.113549.1.12.1.5": "PBE-SHA1-RC2-128",
|
|
52
|
+
"1.2.840.113549.1.12.1.6": "PBE-SHA1-RC2-40",
|
|
53
|
+
[v]: "PBES2"
|
|
54
|
+
};
|
|
55
|
+
function O(...e) {
|
|
56
|
+
let t = 0;
|
|
57
|
+
for (let n of e) t += n.length;
|
|
58
|
+
let n = new Uint8Array(t), r = 0;
|
|
59
|
+
for (let t of e) n.set(t, r), r += t.length;
|
|
60
|
+
return n;
|
|
61
|
+
}
|
|
62
|
+
function k(e, t) {
|
|
63
|
+
if (e.length !== t.length) return !1;
|
|
64
|
+
for (let n = 0; n < e.length; n++) if (e[n] !== t[n]) return !1;
|
|
65
|
+
return !0;
|
|
66
|
+
}
|
|
67
|
+
function A(e) {
|
|
68
|
+
let t = 0;
|
|
69
|
+
for (let n of e.content) t = t * 256 + n;
|
|
70
|
+
return t;
|
|
71
|
+
}
|
|
72
|
+
function j(e) {
|
|
73
|
+
let t = "";
|
|
74
|
+
for (let n of e) t += n.toString(16).padStart(2, "0");
|
|
75
|
+
return t;
|
|
76
|
+
}
|
|
77
|
+
var M = {
|
|
78
|
+
u: 20,
|
|
79
|
+
v: 64,
|
|
80
|
+
hash: (e) => new t().update(e).digest()
|
|
81
|
+
}, N = {
|
|
82
|
+
u: 32,
|
|
83
|
+
v: 64,
|
|
84
|
+
hash: (e) => o(e)
|
|
85
|
+
};
|
|
86
|
+
function P(e, t, n) {
|
|
87
|
+
let r = t.length > e.v ? e.hash(t) : t, i = new Uint8Array(e.v), a = new Uint8Array(e.v);
|
|
88
|
+
i.set(r), a.set(r);
|
|
89
|
+
for (let t = 0; t < e.v; t++) i[t] ^= 54, a[t] ^= 92;
|
|
90
|
+
return e.hash(O(a, e.hash(O(i, n))));
|
|
91
|
+
}
|
|
92
|
+
function F(e, t, n, r, i) {
|
|
93
|
+
let a = new Uint8Array(Math.ceil(i / e.u) * e.u), o = a.length / e.u;
|
|
94
|
+
for (let i = 1; i <= o; i++) {
|
|
95
|
+
let o = P(e, t, O(n, new Uint8Array([
|
|
96
|
+
i >>> 24 & 255,
|
|
97
|
+
i >>> 16 & 255,
|
|
98
|
+
i >>> 8 & 255,
|
|
99
|
+
i & 255
|
|
100
|
+
]))), s = o.slice();
|
|
101
|
+
for (let n = 1; n < r; n++) {
|
|
102
|
+
o = P(e, t, o);
|
|
103
|
+
for (let t = 0; t < e.u; t++) s[t] ^= o[t];
|
|
104
|
+
}
|
|
105
|
+
a.set(s, (i - 1) * e.u);
|
|
106
|
+
}
|
|
107
|
+
return a.subarray(0, i);
|
|
108
|
+
}
|
|
109
|
+
function I(e, t) {
|
|
110
|
+
if (e.length === 0) return new Uint8Array();
|
|
111
|
+
let n = t * Math.ceil(e.length / t), r = new Uint8Array(n);
|
|
112
|
+
for (let t = 0; t < n; t++) r[t] = e[t % e.length];
|
|
113
|
+
return r;
|
|
114
|
+
}
|
|
115
|
+
function L(e, t, n, r, i, a) {
|
|
116
|
+
let { u: o, v: s } = e, c = new Uint8Array(s).fill(i), l = O(I(n, s), I(t, s)), u = new Uint8Array(a), d = 0;
|
|
117
|
+
for (; d < a;) {
|
|
118
|
+
let t = e.hash(O(c, l));
|
|
119
|
+
for (let n = 1; n < r; n++) t = e.hash(t);
|
|
120
|
+
if (u.set(t.subarray(0, Math.min(o, a - d)), d), d += o, d < a) {
|
|
121
|
+
let e = I(t, s);
|
|
122
|
+
for (let t = 0; t < l.length; t += s) {
|
|
123
|
+
let n = 1;
|
|
124
|
+
for (let r = s - 1; r >= 0; r--) {
|
|
125
|
+
let i = l[t + r] + e[r] + n;
|
|
126
|
+
l[t + r] = i & 255, n = i >> 8;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return u;
|
|
132
|
+
}
|
|
133
|
+
function R(e) {
|
|
134
|
+
let t = new Uint8Array(e.length * 2 + 2);
|
|
135
|
+
for (let n = 0; n < e.length; n++) {
|
|
136
|
+
let r = e.charCodeAt(n);
|
|
137
|
+
t[2 * n] = r >>> 8 & 255, t[2 * n + 1] = r & 255;
|
|
138
|
+
}
|
|
139
|
+
return t;
|
|
140
|
+
}
|
|
141
|
+
function z(e, t) {
|
|
142
|
+
let n = new Uint8Array(256);
|
|
143
|
+
for (let e = 0; e < 256; e++) n[e] = e;
|
|
144
|
+
let r = 0;
|
|
145
|
+
for (let t = 0; t < 256; t++) {
|
|
146
|
+
r = r + n[t] + e[t % e.length] & 255;
|
|
147
|
+
let i = n[t];
|
|
148
|
+
n[t] = n[r], n[r] = i;
|
|
149
|
+
}
|
|
150
|
+
let i = new Uint8Array(t.length), a = 0, o = 0;
|
|
151
|
+
for (let e = 0; e < t.length; e++) {
|
|
152
|
+
a = a + 1 & 255, o = o + n[a] & 255;
|
|
153
|
+
let r = n[a];
|
|
154
|
+
n[a] = n[o], n[o] = r, i[e] = t[e] ^ n[n[a] + n[o] & 255];
|
|
155
|
+
}
|
|
156
|
+
return i;
|
|
157
|
+
}
|
|
158
|
+
function B(e, t) {
|
|
159
|
+
if (e.length === 0 || e.length % t !== 0) return null;
|
|
160
|
+
let n = e[e.length - 1];
|
|
161
|
+
if (n < 1 || n > t) return null;
|
|
162
|
+
for (let t = e.length - n; t < e.length; t++) if (e[t] !== n) return null;
|
|
163
|
+
return e.subarray(0, e.length - n);
|
|
164
|
+
}
|
|
165
|
+
var V = class extends Error {};
|
|
166
|
+
function H(e) {
|
|
167
|
+
return i(e.children[0].content);
|
|
168
|
+
}
|
|
169
|
+
function U(e) {
|
|
170
|
+
return e.children.length ? e.children[0] : r(e.content)[0];
|
|
171
|
+
}
|
|
172
|
+
function W(e) {
|
|
173
|
+
return e.constructed ? O(...e.children.map((e) => W(e))) : e.content;
|
|
174
|
+
}
|
|
175
|
+
function G(t, r, a) {
|
|
176
|
+
let o = H(t), l = t.children[1], u = E[o];
|
|
177
|
+
if (u) {
|
|
178
|
+
let e = l.children[0].content, t = A(l.children[1]), n = R(a), i = L(M, n, e, t, 1, u.keyLen);
|
|
179
|
+
if (u.cipher === "rc4") return z(i, r);
|
|
180
|
+
let o = L(M, n, e, t, 2, u.ivLen);
|
|
181
|
+
return B(u.cipher === "3des" ? s(i, o, r) : c(i, o, r, u.effBits), 8);
|
|
182
|
+
}
|
|
183
|
+
if (o === v) {
|
|
184
|
+
let t = l.children[0];
|
|
185
|
+
if (H(t) !== y) throw new V("PBES2 KDF " + H(t));
|
|
186
|
+
let o = t.children[1], c = o.children[0].content, u = A(o.children[1]), d = 0, f = M;
|
|
187
|
+
for (let e = 2; e < o.children.length; e++) {
|
|
188
|
+
let t = o.children[e];
|
|
189
|
+
if (t.tagNumber === n.INTEGER) d = A(t);
|
|
190
|
+
else if (t.tagNumber === n.SEQUENCE) {
|
|
191
|
+
let e = i(t.children[0].content);
|
|
192
|
+
f = e === S ? N : e === x ? M : (() => {
|
|
193
|
+
throw new V("PBKDF2 PRF " + e);
|
|
194
|
+
})();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
let p = l.children[1], m = H(p), h = p.children[1];
|
|
198
|
+
if (T[m]) {
|
|
199
|
+
let t = T[m], n = h.content;
|
|
200
|
+
return B(e(F(f, new TextEncoder().encode(a), c, u, d || t), n, r), 16);
|
|
201
|
+
}
|
|
202
|
+
if (m === b) {
|
|
203
|
+
let e = h.content;
|
|
204
|
+
return B(s(F(f, new TextEncoder().encode(a), c, u, d || 24), e, r), 8);
|
|
205
|
+
}
|
|
206
|
+
throw new V("PBES2 cipher " + m);
|
|
207
|
+
}
|
|
208
|
+
throw new V(D[o] ?? o);
|
|
209
|
+
}
|
|
210
|
+
function K(e) {
|
|
211
|
+
try {
|
|
212
|
+
let t = r(e)[0];
|
|
213
|
+
if (!t || t.tagNumber !== n.SEQUENCE) return !1;
|
|
214
|
+
let a = t.children[0];
|
|
215
|
+
if (!a || a.tagNumber !== n.INTEGER || A(a) !== 3) return !1;
|
|
216
|
+
let o = i(t.children[1].children[0].content);
|
|
217
|
+
return o === l || o === u;
|
|
218
|
+
} catch {
|
|
219
|
+
return !1;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function q(e) {
|
|
223
|
+
return e === C ? "HMAC-SHA1" : e === w ? "HMAC-SHA256" : e;
|
|
224
|
+
}
|
|
225
|
+
function J(e) {
|
|
226
|
+
let t = {};
|
|
227
|
+
if (!e) return t;
|
|
228
|
+
for (let n of e.children) {
|
|
229
|
+
let e = i(n.children[0].content), r = n.children[1]?.children[0];
|
|
230
|
+
if (r) if (e === g) try {
|
|
231
|
+
t.friendlyName = new TextDecoder("utf-16be").decode(r.content);
|
|
232
|
+
} catch {}
|
|
233
|
+
else e === _ && (t.localKeyId = j(r.content));
|
|
234
|
+
}
|
|
235
|
+
return t;
|
|
236
|
+
}
|
|
237
|
+
function Y(e, t) {
|
|
238
|
+
try {
|
|
239
|
+
let o = r(new Uint8Array(e))[0];
|
|
240
|
+
if (!o || o.tagNumber !== n.SEQUENCE) return {
|
|
241
|
+
ok: !1,
|
|
242
|
+
reason: "malformed"
|
|
243
|
+
};
|
|
244
|
+
let s = o.children[1];
|
|
245
|
+
if (!s || i(s.children[0].content) !== l) return {
|
|
246
|
+
ok: !1,
|
|
247
|
+
reason: "unsupported",
|
|
248
|
+
detail: "仅支持口令完整性(pkcs7-data)的 PKCS#12"
|
|
249
|
+
};
|
|
250
|
+
let c = W(U(s.children[1])), u = !1, g = null, _;
|
|
251
|
+
if (o.children.length >= 3) {
|
|
252
|
+
u = !0;
|
|
253
|
+
let e = o.children[2], n = e.children[0], r = i(n.children[0].children[0].content), a = n.children[1].content, s = e.children[1].content, l = e.children[2] ? A(e.children[2]) : 1;
|
|
254
|
+
_ = q(r);
|
|
255
|
+
let d = r === C ? M : r === w ? N : null;
|
|
256
|
+
if (d) {
|
|
257
|
+
if (!k(P(d, L(d, R(t), s, l, 3, d.u), c), a)) return {
|
|
258
|
+
ok: !1,
|
|
259
|
+
reason: "wrong-password"
|
|
260
|
+
};
|
|
261
|
+
g = !0;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
let v = [], y = [], b = /* @__PURE__ */ new Set(), x = [], S = !1, T = (e) => {
|
|
265
|
+
for (let n of e) {
|
|
266
|
+
let e = i(n.children[0].content), r = U(n.children[1]), o = J(n.children[2]);
|
|
267
|
+
if (e === f) i(r.children[0].content) === h && v.push({
|
|
268
|
+
der: W(U(r.children[1])).slice(),
|
|
269
|
+
...o
|
|
270
|
+
});
|
|
271
|
+
else if (e === p) {
|
|
272
|
+
let e = X(r);
|
|
273
|
+
y.push({
|
|
274
|
+
pkcs8: e,
|
|
275
|
+
...a(e),
|
|
276
|
+
...o
|
|
277
|
+
});
|
|
278
|
+
} else if (e === m) {
|
|
279
|
+
let e = r.children[0];
|
|
280
|
+
b.add(D[H(e)] ?? H(e));
|
|
281
|
+
let n;
|
|
282
|
+
try {
|
|
283
|
+
n = G(e, r.children[1].content, t);
|
|
284
|
+
} catch (e) {
|
|
285
|
+
x.push(`私钥加密方式不支持:${e instanceof Error ? e.message : String(e)}`);
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (!n) {
|
|
289
|
+
S = !0;
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
y.push({
|
|
293
|
+
pkcs8: n.slice(),
|
|
294
|
+
...a(n),
|
|
295
|
+
...o
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}, E = r(c)[0];
|
|
300
|
+
for (let e of E.children) {
|
|
301
|
+
let n = i(e.children[0].content);
|
|
302
|
+
if (n === l) {
|
|
303
|
+
let t = r(W(U(e.children[1])))[0];
|
|
304
|
+
t && T(t.children);
|
|
305
|
+
} else if (n === d) {
|
|
306
|
+
let n = U(e.children[1]).children[1], i = n.children[1];
|
|
307
|
+
b.add(D[H(i)] ?? H(i));
|
|
308
|
+
let a = n.children[2], o = a.constructed ? W(a) : a.content, s;
|
|
309
|
+
try {
|
|
310
|
+
s = G(i, o, t);
|
|
311
|
+
} catch (e) {
|
|
312
|
+
x.push(`证书加密方式不支持:${e instanceof Error ? e.message : String(e)}`);
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
if (!s) {
|
|
316
|
+
S = !0;
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
let c = r(s)[0];
|
|
320
|
+
c && T(c.children);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return S && !v.length && !y.length && g !== !0 ? {
|
|
324
|
+
ok: !1,
|
|
325
|
+
reason: "wrong-password"
|
|
326
|
+
} : {
|
|
327
|
+
ok: !0,
|
|
328
|
+
result: {
|
|
329
|
+
macPresent: u,
|
|
330
|
+
macVerified: g,
|
|
331
|
+
macAlgorithm: _,
|
|
332
|
+
certs: v,
|
|
333
|
+
keys: y,
|
|
334
|
+
encryptionAlgos: [...b],
|
|
335
|
+
warnings: x
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
} catch (e) {
|
|
339
|
+
return {
|
|
340
|
+
ok: !1,
|
|
341
|
+
reason: "malformed",
|
|
342
|
+
detail: e instanceof Error ? e.message : String(e)
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function X(e) {
|
|
347
|
+
let t = e.tagClass << 6 | (e.constructed ? 32 : 0) | e.tagNumber, n = e.content.length, r = n < 128 ? [n] : [];
|
|
348
|
+
if (n >= 128) {
|
|
349
|
+
let e = [], t = n;
|
|
350
|
+
for (; t > 0;) e.unshift(t & 255), t >>= 8;
|
|
351
|
+
r.push(128 | e.length, ...e);
|
|
352
|
+
}
|
|
353
|
+
return O(new Uint8Array([t, ...r]), e.content);
|
|
354
|
+
}
|
|
355
|
+
//#endregion
|
|
356
|
+
export { K as looksLikePkcs12, Y as readPkcs12 };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QQ 音乐加密音频(QMCv2)的纯前端解密器 —— 零依赖,照搬 unlock-music / parakeet-crypto 的算法。
|
|
3
|
+
*
|
|
4
|
+
* QQ 音乐客户端下载的「会员歌曲」是被加密的,扩展名形如 `.mflac`(FLAC)、`.mgg`(OGG/Vorbis)、
|
|
5
|
+
* `.qmcflac`/`.qmc0` 等。文件主体是用一段「文件密钥」做的逐字节流加密,密钥本身(EKey)以 base64
|
|
6
|
+
* 形式追加在文件末尾。解出原始密钥后即可还原成标准的 FLAC/OGG/MP3 字节,丢给 <audio> 直接播放。
|
|
7
|
+
*
|
|
8
|
+
* 整条链路(均在浏览器内完成,本函数纯计算、不联网):
|
|
9
|
+
* 1. {@link parseFooter} 解析文件尾,取出 base64 的 EKey 与尾部长度(PC v1 / Android QTag 两种容器)。
|
|
10
|
+
* 2. {@link decryptEKey} 还原文件密钥:base64 解码 → 可选的 EncV2 两轮 TEA → EncV1(8 字节明文头 +
|
|
11
|
+
* 其余走 TC-TEA/CBC 解密,TEA 密钥由「simple key」与密钥头交织而成)。
|
|
12
|
+
* 3. 按密钥长度选择流密码:>300 字节用 {@link rc4Decrypt}(分段 RC4 + 跳表),否则用 {@link mapDecrypt}
|
|
13
|
+
* (把密钥摊成 128 字节查找表逐字节异或)。
|
|
14
|
+
* 4. 去掉尾部,得到明文音频,再用文件头 magic 判定真实格式(fLaC / OggS / ID3·MP3 / ftyp·M4A / WAV)。
|
|
15
|
+
*
|
|
16
|
+
* 这套算法已用本仓库的真实样例逐字节验证:`.mflac` → 合法 FLAC、`.mgg` → 合法 OGG/Vorbis(ffprobe 可解)。
|
|
17
|
+
* 解密是 XOR 流密码,与「加密」同构;这里只做解密。详见 https://git.unlock-music.dev/um/web 。
|
|
18
|
+
*/
|
|
19
|
+
/** 把文件尾的 base64 EKey 字符串还原成文件密钥;失败返回 null。 */
|
|
20
|
+
export declare function decryptEKey(ekey: string): Uint8Array | null;
|
|
21
|
+
export interface QmcFooter {
|
|
22
|
+
/** base64 的 EKey 字符串。 */
|
|
23
|
+
ekey: string;
|
|
24
|
+
/** 需要从文件末尾去掉的字节数(密钥块 + 长度/标记)。 */
|
|
25
|
+
tailLen: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 解析 QMC 文件尾,取出 EKey。支持两种容器:
|
|
29
|
+
* - **PC v1**:末 4 字节小端 = EKey 长度,其前即 EKey(去尾部 0)。
|
|
30
|
+
* - **Android QTag**:末 4 字节为 ASCII "QTag",再往前 4 字节大端为 payload 长度,payload 为
|
|
31
|
+
* `ekey,resourceId,version` 逗号分隔。
|
|
32
|
+
* 解析不出(或像无嵌入密钥的 STag/musicex)返回 null。
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseFooter(buf: Uint8Array): QmcFooter | null;
|
|
35
|
+
export interface QmcDecrypted {
|
|
36
|
+
data: Uint8Array;
|
|
37
|
+
/** 探测出的真实格式:flac / ogg / mp3 / m4a / wav / bin。 */
|
|
38
|
+
format: string;
|
|
39
|
+
/** 对应的 MIME,用于 <audio> 的 Blob。 */
|
|
40
|
+
mime: string;
|
|
41
|
+
/** 建议的下载扩展名(不含点)。 */
|
|
42
|
+
ext: string;
|
|
43
|
+
}
|
|
44
|
+
export declare class QmcError extends Error {
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 解密一个 QMC 加密音频。`input` 是整个文件字节。成功返回明文音频 + 探测出的格式信息;
|
|
48
|
+
* 解析/解密失败抛 {@link QmcError}(调用方据此给出友好提示)。
|
|
49
|
+
*/
|
|
50
|
+
export declare function decryptQmc(input: ArrayBuffer | Uint8Array): QmcDecrypted;
|
package/dist/lib/qmc.js
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
//#region src/lib/qmc.ts
|
|
2
|
+
var e = 16, t = 2654435769, n = (e) => e >>> 0, r = (e, t) => n(e + t), i = (e, t) => n(e - t);
|
|
3
|
+
function a(e, t) {
|
|
4
|
+
return n(e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3]);
|
|
5
|
+
}
|
|
6
|
+
function o(e, t, n) {
|
|
7
|
+
e[t] = n >>> 24 & 255, e[t + 1] = n >>> 16 & 255, e[t + 2] = n >>> 8 & 255, e[t + 3] = n & 255;
|
|
8
|
+
}
|
|
9
|
+
function s(e, t, i, a) {
|
|
10
|
+
return n(r(n(e << 4), i) ^ r(t, e) ^ r(e >>> 5, a));
|
|
11
|
+
}
|
|
12
|
+
function c(r, c, l) {
|
|
13
|
+
let u = a(r, c), d = a(r, c + 4), f = n(t * e);
|
|
14
|
+
for (let n = 0; n < e; n++) d = i(d, s(u, f, l[2], l[3])), u = i(u, s(d, f, l[0], l[1])), f = i(f, t);
|
|
15
|
+
o(r, c, u), o(r, c + 4, d);
|
|
16
|
+
}
|
|
17
|
+
var l = 2, u = 7, d = 10;
|
|
18
|
+
function f(e, t) {
|
|
19
|
+
if (t.length < 16) return null;
|
|
20
|
+
let n = [
|
|
21
|
+
a(t, 0),
|
|
22
|
+
a(t, 4),
|
|
23
|
+
a(t, 8),
|
|
24
|
+
a(t, 12)
|
|
25
|
+
], r = e.length;
|
|
26
|
+
if (r < d || r % 8 != 0) return null;
|
|
27
|
+
let i = e.slice();
|
|
28
|
+
c(i, 0, n);
|
|
29
|
+
for (let e = 8; e < r; e += 8) {
|
|
30
|
+
for (let t = 0; t < 8; t++) i[e + t] ^= i[e - 8 + t];
|
|
31
|
+
c(i, e, n);
|
|
32
|
+
}
|
|
33
|
+
for (let t = 8; t < r; t++) i[t] ^= e[t - 8];
|
|
34
|
+
let o = 1 + (i[0] & 7) + l, s = r - u;
|
|
35
|
+
if (o > s) return null;
|
|
36
|
+
for (let e = s; e < r; e++) if (i[e] !== 0) return null;
|
|
37
|
+
return i.slice(o, s);
|
|
38
|
+
}
|
|
39
|
+
var p = "UVFNdXNpYyBFbmNWMixLZXk6", m = v("386ZJY!@#*$%^&)("), h = v("**#!(#$%&^a1cZ,T"), g = 106, _ = 1280;
|
|
40
|
+
function v(e) {
|
|
41
|
+
let t = new Uint8Array(e.length);
|
|
42
|
+
for (let n = 0; n < e.length; n++) t[n] = e.charCodeAt(n) & 255;
|
|
43
|
+
return t;
|
|
44
|
+
}
|
|
45
|
+
function y(e) {
|
|
46
|
+
let t = e.replace(/[^A-Za-z0-9+/]/g, ""), n = t + "=".repeat((4 - t.length % 4) % 4), r = atob(n), i = new Uint8Array(r.length);
|
|
47
|
+
for (let e = 0; e < r.length; e++) i[e] = r.charCodeAt(e);
|
|
48
|
+
return i;
|
|
49
|
+
}
|
|
50
|
+
function b() {
|
|
51
|
+
let e = new Uint8Array(8);
|
|
52
|
+
for (let t = 0; t < 8; t++) e[t] = Math.trunc(Math.abs(Math.tan(g + t * .1)) * 100) & 255;
|
|
53
|
+
return e;
|
|
54
|
+
}
|
|
55
|
+
var x = b();
|
|
56
|
+
function S(e) {
|
|
57
|
+
if (e.length < 8) return null;
|
|
58
|
+
let t = e.slice(0, 8), n = e.slice(8), r = new Uint8Array(16);
|
|
59
|
+
for (let e = 0; e < 8; e++) r[e * 2] = x[e], r[e * 2 + 1] = t[e];
|
|
60
|
+
let i = f(n, r);
|
|
61
|
+
if (!i) return null;
|
|
62
|
+
let a = new Uint8Array(8 + i.length);
|
|
63
|
+
return a.set(t, 0), a.set(i, 8), a;
|
|
64
|
+
}
|
|
65
|
+
function C(e) {
|
|
66
|
+
let t = e.replace(/\s+/g, "");
|
|
67
|
+
if (t.startsWith(p)) {
|
|
68
|
+
let e = y(t.slice(24));
|
|
69
|
+
if (e = f(e, m), !e || (e = f(e, h), !e)) return null;
|
|
70
|
+
let n = "";
|
|
71
|
+
for (let t of e) n += String.fromCharCode(t);
|
|
72
|
+
return S(y(n));
|
|
73
|
+
}
|
|
74
|
+
return S(y(t));
|
|
75
|
+
}
|
|
76
|
+
var w = new TextDecoder("latin1");
|
|
77
|
+
function T(e) {
|
|
78
|
+
if (e.length < 8) return null;
|
|
79
|
+
if (w.decode(e.subarray(e.length - 4)) === "QTag") {
|
|
80
|
+
let t = a(e, e.length - 8) + 8;
|
|
81
|
+
if (t > e.length) return null;
|
|
82
|
+
let n = w.decode(e.subarray(e.length - t, e.length - 8)).split(",")[0];
|
|
83
|
+
return n ? {
|
|
84
|
+
ekey: n,
|
|
85
|
+
tailLen: t
|
|
86
|
+
} : null;
|
|
87
|
+
}
|
|
88
|
+
let t = n(e[e.length - 4] | e[e.length - 3] << 8 | e[e.length - 2] << 16 | e[e.length - 1] << 24);
|
|
89
|
+
if (t === 0 || t > _ || t + 4 > e.length) return null;
|
|
90
|
+
let r = e.length - 4, i = r - t;
|
|
91
|
+
for (; r > i && e[r - 1] === 0;) r--;
|
|
92
|
+
let o = w.decode(e.subarray(i, r));
|
|
93
|
+
return /^[A-Za-z0-9+/=]+$/.test(o) ? {
|
|
94
|
+
ekey: o,
|
|
95
|
+
tailLen: t + 4
|
|
96
|
+
} : null;
|
|
97
|
+
}
|
|
98
|
+
function E(e) {
|
|
99
|
+
let t = new Uint8Array(128), n = e.length;
|
|
100
|
+
if (n === 0) return t;
|
|
101
|
+
let r = new Uint8Array(n), i = 4;
|
|
102
|
+
for (let t = 0; t < n; t++) {
|
|
103
|
+
let n = e[t];
|
|
104
|
+
r[t] = (n << i & 255 | n >>> i) & 255, i = i + 1 & 7;
|
|
105
|
+
}
|
|
106
|
+
for (let e = 0; e < 128; e++) t[e] = r[(e * e + 71214) % n];
|
|
107
|
+
return t;
|
|
108
|
+
}
|
|
109
|
+
function D(e, t) {
|
|
110
|
+
let n = E(t);
|
|
111
|
+
for (let t = 0; t < e.length; t++) {
|
|
112
|
+
let r = t;
|
|
113
|
+
r > 32767 && (r %= 32767), e[t] ^= n[r & 127];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
var O = 128, k = 5120, A = 5631;
|
|
117
|
+
function j(e, t) {
|
|
118
|
+
let n = e.length, r = new Uint8Array(n);
|
|
119
|
+
for (let e = 0; e < n; e++) r[e] = e & 255;
|
|
120
|
+
let i = 0;
|
|
121
|
+
for (let t = 0; t < n; t++) {
|
|
122
|
+
i = (i + r[t] + e[t % n]) % n;
|
|
123
|
+
let a = r[t];
|
|
124
|
+
r[t] = r[i], r[i] = a;
|
|
125
|
+
}
|
|
126
|
+
let a = new Uint8Array(t), o = 0;
|
|
127
|
+
i = 0;
|
|
128
|
+
for (let e = 0; e < t; e++) {
|
|
129
|
+
o = (o + 1) % n, i = (i + r[o]) % n;
|
|
130
|
+
let t = r[o];
|
|
131
|
+
r[o] = r[i], r[i] = t, a[e] = r[(r[o] + r[i]) % n];
|
|
132
|
+
}
|
|
133
|
+
return a;
|
|
134
|
+
}
|
|
135
|
+
function M(e) {
|
|
136
|
+
let t = 1;
|
|
137
|
+
for (let n = 0; n < e.length; n++) {
|
|
138
|
+
let r = e[n];
|
|
139
|
+
if (r === 0) continue;
|
|
140
|
+
let i = Math.imul(t, r) >>> 0;
|
|
141
|
+
if (i <= t >>> 0) break;
|
|
142
|
+
t = i;
|
|
143
|
+
}
|
|
144
|
+
return t >>> 0;
|
|
145
|
+
}
|
|
146
|
+
function N(e, t) {
|
|
147
|
+
let n = t.length, r = M(t), i = j(t, A), a = (e, t) => t === 0 ? 0 : Math.floor(r / (t * (e + 1)) * 100), o = 0, s = 0, c = e.length;
|
|
148
|
+
if (o < O) {
|
|
149
|
+
let r = Math.min(c - s, O - o), i = o;
|
|
150
|
+
for (let o = 0; o < r; o++) e[s + o] ^= t[a(i, t[i % n]) % n], i++;
|
|
151
|
+
o += r, s += r;
|
|
152
|
+
}
|
|
153
|
+
if (o % k !== 0) {
|
|
154
|
+
let t = Math.min(c - s, k - o % k);
|
|
155
|
+
l(e, s, t, o), o += t, s += t;
|
|
156
|
+
}
|
|
157
|
+
for (; s < c;) {
|
|
158
|
+
let t = Math.min(c - s, k);
|
|
159
|
+
l(e, s, t, o), o += t, s += t;
|
|
160
|
+
}
|
|
161
|
+
function l(e, r, o, s) {
|
|
162
|
+
let c = Math.floor(s / k), l = s % k, u = a(c, t[c % n]) % 512 + l;
|
|
163
|
+
for (let t = 0; t < o; t++) e[r + t] ^= i[u + t];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function P(e) {
|
|
167
|
+
let t = (t, n) => {
|
|
168
|
+
for (let r = 0; r < n.length; r++) if (e[t + r] !== n.charCodeAt(r)) return !1;
|
|
169
|
+
return !0;
|
|
170
|
+
};
|
|
171
|
+
return t(0, "fLaC") ? {
|
|
172
|
+
format: "flac",
|
|
173
|
+
mime: "audio/flac",
|
|
174
|
+
ext: "flac"
|
|
175
|
+
} : t(0, "OggS") ? {
|
|
176
|
+
format: "ogg",
|
|
177
|
+
mime: "audio/ogg",
|
|
178
|
+
ext: "ogg"
|
|
179
|
+
} : t(0, "ID3") || e[0] === 255 && (e[1] & 224) == 224 ? {
|
|
180
|
+
format: "mp3",
|
|
181
|
+
mime: "audio/mpeg",
|
|
182
|
+
ext: "mp3"
|
|
183
|
+
} : e.length > 11 && t(4, "ftyp") ? {
|
|
184
|
+
format: "m4a",
|
|
185
|
+
mime: "audio/mp4",
|
|
186
|
+
ext: "m4a"
|
|
187
|
+
} : t(0, "RIFF") && t(8, "WAVE") ? {
|
|
188
|
+
format: "wav",
|
|
189
|
+
mime: "audio/wav",
|
|
190
|
+
ext: "wav"
|
|
191
|
+
} : {
|
|
192
|
+
format: "bin",
|
|
193
|
+
mime: "application/octet-stream",
|
|
194
|
+
ext: "bin"
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
var F = class extends Error {};
|
|
198
|
+
function I(e) {
|
|
199
|
+
let t = e instanceof Uint8Array ? e : new Uint8Array(e), n = T(t);
|
|
200
|
+
if (!n) throw new F("未能解析文件尾部的密钥(可能不是 QQ 音乐加密文件,或为需要外部密钥的 STag 格式)");
|
|
201
|
+
let r = C(n.ekey);
|
|
202
|
+
if (!r || r.length === 0) throw new F("EKey 解密失败");
|
|
203
|
+
let i = t.slice(0, t.length - n.tailLen);
|
|
204
|
+
r.length > 300 ? N(i, r) : D(i, r);
|
|
205
|
+
let a = P(i);
|
|
206
|
+
if (a.format === "bin") throw new F("解密结果不是可识别的音频格式(密钥或格式不支持)");
|
|
207
|
+
return {
|
|
208
|
+
data: i,
|
|
209
|
+
...a
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
//#endregion
|
|
213
|
+
export { F as QmcError, C as decryptEKey, I as decryptQmc, T as parseFooter };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-browser RAR reader, wrapping the WASM unrar port (node-unrar-js).
|
|
3
|
+
*
|
|
4
|
+
* RAR is the one archive format in this viewer we don't hand-roll: RAR3/RAR5 decompression is a large,
|
|
5
|
+
* proprietary LZ+filter pipeline, so — unlike zip/7z/tar — we lean on the upstream `unrar` C sources
|
|
6
|
+
* compiled to WebAssembly. The ESM build (`node-unrar-js/esm`) is browser-targeted; we feed it the wasm
|
|
7
|
+
* binary fetched as a same-origin asset (Vite emits `unrar.wasm` via the `?url` import) so nothing loads
|
|
8
|
+
* from a CDN. The module + wasm are pulled in lazily (this file is dynamic-imported by ArchiveBrowser),
|
|
9
|
+
* keeping the ~200KB wasm out of the main bundle until a `.rar` is actually opened.
|
|
10
|
+
*
|
|
11
|
+
* Exposed through the shared {@link OpenedArchive} interface like the other archives. The upstream bytes are
|
|
12
|
+
* decoded entirely client-side; the WASM sandbox never reaches the network or filesystem.
|
|
13
|
+
*/
|
|
14
|
+
import type { OpenedArchive } from '@/lib/archive';
|
|
15
|
+
/** Open a RAR archive: list its entries, extracting each file's bytes on demand via the WASM extractor. */
|
|
16
|
+
export declare function openRar(buf: ArrayBuffer): Promise<OpenedArchive>;
|