mirror of
https://github.com/remotely-save/remotely-save.git
synced 2024-06-07 21:10:45 +00:00
fix encrypt method
This commit is contained in:
parent
62452341a3
commit
02e03681f7
@ -42,9 +42,18 @@ export class Cipher {
|
||||
return content;
|
||||
}
|
||||
if (this.method === "openssl-base64") {
|
||||
return await openssl.encryptArrayBuffer(content, this.password);
|
||||
const res = await openssl.encryptArrayBuffer(content, this.password);
|
||||
if (res === undefined) {
|
||||
throw Error(`cannot encrypt content`);
|
||||
}
|
||||
return res;
|
||||
} else if (this.method === "rclone-base64") {
|
||||
return await this.cipherRClone!.encryptContentByCallingWorker(content);
|
||||
const res =
|
||||
await this.cipherRClone!.encryptContentByCallingWorker(content);
|
||||
if (res === undefined) {
|
||||
throw Error(`cannot encrypt content`);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
throw Error(`not supported encrypt method=${this.method}`);
|
||||
}
|
||||
@ -56,9 +65,18 @@ export class Cipher {
|
||||
return content;
|
||||
}
|
||||
if (this.method === "openssl-base64") {
|
||||
return await openssl.decryptArrayBuffer(content, this.password);
|
||||
const res = await openssl.decryptArrayBuffer(content, this.password);
|
||||
if (res === undefined) {
|
||||
throw Error(`cannot decrypt content`);
|
||||
}
|
||||
return res;
|
||||
} else if (this.method === "rclone-base64") {
|
||||
return await this.cipherRClone!.decryptContentByCallingWorker(content);
|
||||
const res =
|
||||
await this.cipherRClone!.decryptContentByCallingWorker(content);
|
||||
if (res === undefined) {
|
||||
throw Error(`cannot decrypt content`);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
throw Error(`not supported decrypt method=${this.method}`);
|
||||
}
|
||||
@ -70,15 +88,23 @@ export class Cipher {
|
||||
return name;
|
||||
}
|
||||
if (this.method === "openssl-base64") {
|
||||
return await openssl.encryptStringToBase64url(name, this.password);
|
||||
const res = await openssl.encryptStringToBase64url(name, this.password);
|
||||
if (res === undefined) {
|
||||
throw Error(`cannot encrypt name=${name}`);
|
||||
}
|
||||
return res;
|
||||
} else if (this.method === "rclone-base64") {
|
||||
return await this.cipherRClone!.encryptNameByCallingWorker(name);
|
||||
const res = await this.cipherRClone!.encryptNameByCallingWorker(name);
|
||||
if (res === undefined) {
|
||||
throw Error(`cannot encrypt name=${name}`);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
throw Error(`not supported encrypt method=${this.method}`);
|
||||
}
|
||||
}
|
||||
|
||||
async decryptName(name: string) {
|
||||
async decryptName(name: string): Promise<string> {
|
||||
// console.debug("start decryptName");
|
||||
if (this.password === "") {
|
||||
return name;
|
||||
@ -88,7 +114,7 @@ export class Cipher {
|
||||
// backward compitable with the openssl-base32
|
||||
try {
|
||||
const res = await openssl.decryptBase32ToString(name, this.password);
|
||||
if (isVaildText(res)) {
|
||||
if (res !== undefined && isVaildText(res)) {
|
||||
return res;
|
||||
} else {
|
||||
throw Error(`cannot decrypt name=${name}`);
|
||||
@ -102,7 +128,7 @@ export class Cipher {
|
||||
name,
|
||||
this.password
|
||||
);
|
||||
if (isVaildText(res)) {
|
||||
if (res !== undefined && isVaildText(res)) {
|
||||
return res;
|
||||
} else {
|
||||
throw Error(`cannot decrypt name=${name}`);
|
||||
@ -110,9 +136,17 @@ export class Cipher {
|
||||
} catch (error) {
|
||||
throw Error(`cannot decrypt name=${name}`);
|
||||
}
|
||||
} else {
|
||||
throw Error(
|
||||
`method=${this.method} but the name=${name}, likely mismatch`
|
||||
);
|
||||
}
|
||||
} else if (this.method === "rclone-base64") {
|
||||
return await this.cipherRClone!.decryptNameByCallingWorker(name);
|
||||
const res = await this.cipherRClone!.decryptNameByCallingWorker(name);
|
||||
if (res === undefined) {
|
||||
throw Error(`cannot decrypt name=${name}`);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
throw Error(`not supported decrypt method=${this.method}`);
|
||||
}
|
||||
@ -136,7 +170,7 @@ export class Cipher {
|
||||
* @param name
|
||||
* @returns
|
||||
*/
|
||||
static isLikelyEncryptedName(name: string): boolean {
|
||||
static isLikelyOpenSSLEncryptedName(name: string): boolean {
|
||||
if (
|
||||
name.startsWith(openssl.MAGIC_ENCRYPTED_PREFIX_BASE32) ||
|
||||
name.startsWith(openssl.MAGIC_ENCRYPTED_PREFIX_BASE64URL)
|
||||
@ -145,4 +179,37 @@ export class Cipher {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* quick guess, no actual decryption here
|
||||
* @param name
|
||||
* @returns
|
||||
*/
|
||||
static isLikelyEncryptedName(name: string): boolean {
|
||||
return Cipher.isLikelyOpenSSLEncryptedName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* quick guess, no actual decryption here, only openssl can be guessed here
|
||||
* @param name
|
||||
* @returns
|
||||
*/
|
||||
static isLikelyEncryptedNameNotMatchMethod(
|
||||
name: string,
|
||||
method: CipherMethodType
|
||||
): boolean {
|
||||
if (
|
||||
Cipher.isLikelyOpenSSLEncryptedName(name) &&
|
||||
method !== "openssl-base64"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
!Cipher.isLikelyOpenSSLEncryptedName(name) &&
|
||||
method === "openssl-base64"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -165,6 +165,9 @@ export const base64ToBase64url = (a: string, pad: boolean = false) => {
|
||||
* @param a
|
||||
*/
|
||||
export const isVaildText = (a: string) => {
|
||||
if (a === undefined) {
|
||||
return false;
|
||||
}
|
||||
// If the regex matches, the string is invalid.
|
||||
return !XRegExp("\\p{Cc}|\\p{Cf}|\\p{Co}|\\p{Cn}|\\p{Zl}|\\p{Zp}", "A").test(
|
||||
a
|
||||
|
@ -125,15 +125,9 @@ class PasswordModal extends Modal {
|
||||
|
||||
class EncryptionMethodModal extends Modal {
|
||||
plugin: RemotelySavePlugin;
|
||||
newEncryptionMethod: CipherMethodType;
|
||||
constructor(
|
||||
app: App,
|
||||
plugin: RemotelySavePlugin,
|
||||
newEncryptionMethod: CipherMethodType
|
||||
) {
|
||||
constructor(app: App, plugin: RemotelySavePlugin) {
|
||||
super(app);
|
||||
this.plugin = plugin;
|
||||
this.newEncryptionMethod = newEncryptionMethod;
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
@ -153,22 +147,13 @@ class EncryptionMethodModal extends Modal {
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(contentEl)
|
||||
.addButton((button) => {
|
||||
button.setButtonText(t("confirm"));
|
||||
button.onClick(async () => {
|
||||
this.plugin.settings.encryptionMethod = this.newEncryptionMethod;
|
||||
await this.plugin.saveSettings();
|
||||
this.close();
|
||||
});
|
||||
button.setClass("encryptionmethod-second-confirm");
|
||||
})
|
||||
.addButton((button) => {
|
||||
button.setButtonText(t("goback"));
|
||||
button.onClick(() => {
|
||||
this.close();
|
||||
});
|
||||
new Setting(contentEl).addButton((button) => {
|
||||
button.setButtonText(t("confirm"));
|
||||
button.onClick(async () => {
|
||||
this.close();
|
||||
});
|
||||
button.setClass("encryptionmethod-second-confirm");
|
||||
});
|
||||
}
|
||||
|
||||
onClose() {
|
||||
@ -1693,26 +1678,17 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
|
||||
.setName(t("settings_encryptionmethod"))
|
||||
.setDesc(stringToFragment(t("settings_encryptionmethod_desc")))
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown.addOption(
|
||||
"rclone-base64",
|
||||
t("settings_encryptionmethod_rclone")
|
||||
);
|
||||
dropdown.addOption(
|
||||
"openssl-base64",
|
||||
t("settings_encryptionmethod_openssl")
|
||||
);
|
||||
dropdown.onChange(async (val: string) => {
|
||||
if (this.plugin.settings.password === "") {
|
||||
dropdown
|
||||
.addOption("rclone-base64", t("settings_encryptionmethod_rclone"))
|
||||
.addOption("openssl-base64", t("settings_encryptionmethod_openssl"))
|
||||
.setValue(this.plugin.settings.encryptionMethod ?? "rclone-base64")
|
||||
.onChange(async (val: string) => {
|
||||
this.plugin.settings.encryptionMethod = val as CipherMethodType;
|
||||
await this.plugin.saveSettings();
|
||||
} else {
|
||||
new EncryptionMethodModal(
|
||||
this.app,
|
||||
this.plugin,
|
||||
val as CipherMethodType
|
||||
).open();
|
||||
}
|
||||
});
|
||||
if (this.plugin.settings.password !== "") {
|
||||
new EncryptionMethodModal(this.app, this.plugin).open();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(basicDiv)
|
||||
|
20
src/sync.ts
20
src/sync.ts
@ -53,8 +53,9 @@ export interface PasswordCheckType {
|
||||
| "unknown_encryption_method"
|
||||
| "remote_encrypted_local_no_password"
|
||||
| "password_matched"
|
||||
| "password_not_matched_or_remote_not_encrypted"
|
||||
| "likely_no_password_both_sides";
|
||||
| "password_or_method_not_matched_or_remote_not_encrypted"
|
||||
| "likely_no_password_both_sides"
|
||||
| "encryption_method_not_matched";
|
||||
}
|
||||
|
||||
export const isPasswordOk = async (
|
||||
@ -91,8 +92,19 @@ export const isPasswordOk = async (
|
||||
reason: "unknown_encryption_method",
|
||||
};
|
||||
}
|
||||
if (
|
||||
Cipher.isLikelyEncryptedNameNotMatchMethod(santyCheckKey, cipher.method)
|
||||
) {
|
||||
return {
|
||||
ok: false,
|
||||
reason: "encryption_method_not_matched",
|
||||
};
|
||||
}
|
||||
try {
|
||||
await cipher.decryptName(santyCheckKey);
|
||||
const k = await cipher.decryptName(santyCheckKey);
|
||||
if (k === undefined) {
|
||||
throw Error(`decryption failed`);
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
reason: "password_matched",
|
||||
@ -100,7 +112,7 @@ export const isPasswordOk = async (
|
||||
} catch (error) {
|
||||
return {
|
||||
ok: false,
|
||||
reason: "password_not_matched_or_remote_not_encrypted",
|
||||
reason: "password_or_method_not_matched_or_remote_not_encrypted",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user