Crypt

Crypt

Rclone 的 crypt 远程存储用于对其他远程存储进行加密和解密操作。

类型为 crypt 的远程存储并不直接访问 存储系统,而是对另一个远程存储进行封装,由被封装的远程存储来访问存储系统。这与 别名联合分块器 等功能的工作方式类似。这种设计使得使用方式非常灵活,你可以在任何其他后端之上添加一层(这里是加密层),甚至可以添加多层。Rclone 的功能可以像使用其他远程存储一样使用,例如你可以 挂载 一个 crypt 远程存储。

通过 crypt 远程存储访问存储系统实现了客户端加密,这使得你可以安全地将数据存放在你不信任的位置,不用担心数据被泄露。 当对 crypt 远程存储进行操作时,rclone 会根据需要在本地系统上自动进行加密(上传前)和解密(下载后)操作,使得数据在被封装的远程存储中处于加密状态。如果你使用 rclone 以外的应用程序访问存储系统,或者直接使用 rclone 访问被封装的远程存储,将不会进行任何加密/解密操作:下载现有内容将得到加密(乱码)格式,而你上传的任何内容 不会 被加密。

加密采用的是密钥加密算法(也称为对称密钥加密),通过一个密码(或密码短语)来生成实际的加密密钥。密码可以由用户提供,也可以让 rclone 自动生成。密码将以轻度混淆的形式存储在配置文件中。 如果你所处的环境无法确保配置文件的安全,你应该添加 配置加密 作为保护措施。只要你拥有这个配置文件,就可以解密你的数据。如果没有配置文件,只要你记得密码(或将其保存在安全的地方),就可以重新创建配置并访问现有数据。你还可以在不同的安装环境中配置相应的远程存储来访问相同的数据。 有关 更改密码 的指导,请参阅下文。

加密使用 加密盐 来改变加密密钥,从而使相同的字符串可以以不同的方式进行加密。在配置 crypt 远程存储时,可以选择输入一个盐,也可以让 rclone 生成一个唯一的盐。如果省略该步骤,rclone 将使用内置的唯一字符串。 通常在密码学中,盐会与加密内容一起存储,用户无需记住它。但在 rclone 中并非如此,因为 rclone 不会在远程存储中存储任何额外的信息。使用自定义盐实际上相当于第二个必须记住的密码。

文件内容 加密使用 NaCl SecretBox 进行,它基于 XSalsa20 密码和 Poly1305 进行完整性验证。 名称(文件名和目录名)默认情况下也会被加密,但这有一些影响,因此也可以选择关闭此功能。

配置

以下是一个如何创建名为 secret 的远程存储的示例。

要使用 crypt,首先需要设置底层的远程存储。按照 rclone config 针对特定后端的说明进行操作。

在配置 crypt 远程存储之前,确保底层的远程存储可以正常工作。在这个示例中,底层的远程存储名为 remote。 我们将在这个远程存储中配置一个路径 path 来存储加密内容。remote:path 内的任何内容都将被加密,而外部的内容则不会。

使用 rclone config 配置 crypt。在这个示例中,crypt 远程存储名为 secret,以区别于底层的 remote

配置完成后,你可以像使用其他远程存储一样使用名为 secretcrypt 远程存储,例如 rclone copy D:\docs secret:\docs,rclone 会根据需要自动进行加密和解密操作。 如果你直接访问被封装的远程存储 remote:path,将绕过加密过程,读取的内容将是加密形式,而写入的内容将不会被加密。为避免出现问题,最好为加密内容配置一个专用路径,并仅通过 crypt 远程存储访问它。

No remotes found, make a new one?
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n
name> secret
Type of storage to configure.
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value
[snip]
XX / Encrypt/Decrypt a remote
   \ "crypt"
[snip]
Storage> crypt
** See help for crypt backend at: https://rclone.cn/crypt/ **

Remote to encrypt/decrypt.
Normally should contain a ':' and a path, eg "myremote:path/to/dir",
"myremote:bucket" or maybe "myremote:" (not recommended).
Enter a string value. Press Enter for the default ("").
remote> remote:path
How to encrypt the filenames.
Enter a string value. Press Enter for the default ("standard").
Choose a number from below, or type in your own value.
   / Encrypt the filenames.
 1 | See the docs for the details.
   \ "standard"
 2 / Very simple filename obfuscation.
   \ "obfuscate"
   / Don't encrypt the file names.
 3 | Adds a ".bin" extension only.
   \ "off"
filename_encryption>
Option to either encrypt directory names or leave them intact.

NB If filename_encryption is "off" then this option will do nothing.
Enter a boolean value (true or false). Press Enter for the default ("true").
Choose a number from below, or type in your own value
 1 / Encrypt directory names.
   \ "true"
 2 / Don't encrypt directory names, leave them intact.
   \ "false"
directory_name_encryption>
Password or pass phrase for encryption.
y) Yes type in my own password
g) Generate random password
y/g> y
Enter the password:
password:
Confirm the password:
password:
Password or pass phrase for salt. Optional but recommended.
Should be different to the previous password.
y) Yes type in my own password
g) Generate random password
n) No leave this optional password blank (default)
y/g/n> g
Password strength in bits.
64 is just about memorable
128 is secure
1024 is the maximum
Bits> 128
Your password is: JAsJvRcgR-_veXNfy_sGmQ
Use this password? Please note that an obscured version of this
password (and not the password itself) will be stored under your
configuration file, so keep this generated password in a safe place.
y) Yes (default)
n) No
y/n>
Edit advanced config? (y/n)
y) Yes
n) No (default)
y/n>
Remote config
--------------------
[secret]
type = crypt
remote = remote:path
password = *** ENCRYPTED ***
password2 = *** ENCRYPTED ***
--------------------
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d>

[]: # … existing code …

重要提示:存储在 rclone.conf 中的加密密码仅做了轻度混淆处理。这只能防止他人随意查看,并不安全,除非对 rclone.conf 文件进行了 配置加密

建议使用长密码短语,或者使用 rclone config 命令自动生成一个随机密码。

混淆后的密码是使用带有静态密钥的 AES-CTR 算法生成的。初始向量(IV,即随机数)会原样存储在混淆后密码的开头。这个静态密钥在所有版本的 rclone 中都是相同的。

如果你在其他地方使用相同的密码或密码短语重新配置 rclone,它们是兼容的,但由于使用的盐不同,混淆后的密码会有所差异。

Rclone 不会对以下内容进行加密:

  • 文件长度 - 可以在 16 字节的误差范围内计算得出
  • 修改时间 - 用于同步操作

指定远程存储

在配置要加密或解密的远程存储时,你可以指定 rclone 支持的任何字符串作为其他命令的源或目标。

主要的使用场景是指定一个已配置好的远程存储路径(例如 remote:path/to/dirremote:bucket),这样就可以将远程不可信位置的数据进行加密存储。

你也可以指定本地文件系统路径,例如 Linux 上的 /path/to/dir,Windows 上的 C:\path\to\dir。通过创建一个指向本地文件系统路径的加密远程存储,你可以将 rclone 用作纯粹的本地文件加密工具,例如将加密文件存储在可移动的 USB 驱动器上。

注意:如果字符串中不包含 :,rclone 会将其视为本地文件系统的相对路径。例如,如果你输入 remote 而没有尾随的 :,它将被视为当前目录下名为 “remote” 的子目录。

如果指定了路径 remote:path/to/dir,rclone 会将加密文件存储在远程存储的 path/to/dir 中。启用文件名加密后,保存到 secret:subdir/subfile 的文件会存储在未加密的路径 path/to/dir 中,但 subdir/subpath 部分会被加密。

你指定的路径不一定需要存在,rclone 会在需要时创建它。

如果你打算直接使用包装后的远程存储来保存未加密内容,同时也通过加密远程存储来保存加密内容,建议将加密远程存储指向包装后远程存储中的一个单独目录。如果你使用基于存储桶的存储系统(例如 Swift、S3、Google Compute Storage、B2),通常建议将加密远程存储包装在一个特定的存储桶上(例如 s3:bucket)。如果将其包装在整个存储根目录上(例如 s3:),并启用了可选的文件名加密功能,rclone 会对存储桶名称进行加密。

更改密码

如果密码或包含轻度混淆密码的配置文件被泄露,你需要使用新密码重新加密数据。由于 rclone 使用密钥加密算法,加密密钥直接由客户端保存的密码生成,因此无法更改已加密内容的密码或密钥。仅仅更改现有加密远程存储的配置密码意味着你将无法解密之前加密的任何内容。唯一的办法是通过使用新密码配置的加密远程存储重新上传所有内容。

根据你的数据大小、带宽、存储配额等因素,你可以采取以下不同的方法:

  • 如果你在其他位置(例如本地系统)保存了所有数据,你可以删除之前所有的加密文件,更改已配置的加密远程存储的密码(或者删除并重新创建加密配置),然后从其他位置重新上传所有内容。
  • 如果你在存储系统上有足够的空间,你可以创建一个新的加密远程存储,指向同一后端的一个单独目录,然后使用 rclone 将所有内容从原始加密远程存储复制到新的远程存储,这样实际上是在传输过程中使用旧密码解密所有内容,并使用新密码重新加密。完成后,删除原始加密远程存储目录,最后删除使用旧密码的 rclone 加密配置。所有数据都会从存储系统中流式传输并返回,因此你的带宽利用率会减半,并且如果存储系统对上传和下载有配额限制,你将被收取双倍费用。

注意:rclone 1.53.3 版本(2020 年 11 月 19 日发布)修复了随机密码生成器的一个安全问题。在 1.49.0 版本(2019 年 8 月 26 日发布)至 1.53.2 版本(2020 年 10 月 26 日发布)期间,使用 rclone config 生成的密码被认为不安全,应该进行更改。如果你自己设置了密码,或者使用早于 1.49.0 版本或晚于 1.53.2 版本的 rclone 生成密码,则 不受此问题影响。有关更多详细信息以及可用于检查是否受影响的工具,请参阅 问题 #4783

示例

使用 “标准” 文件名加密方式创建以下文件结构。

plaintext/
├── file0.txt
├── file1.txt
└── subdir
    ├── file2.txt
    ├── file3.txt
    └── subsubdir
        └── file4.txt

Copy these to the remote, and list them

$ rclone -q copy plaintext secret:
$ rclone -q ls secret:
        7 file1.txt
        6 file0.txt
        8 subdir/file2.txt
       10 subdir/subsubdir/file4.txt
        9 subdir/file3.txt

The crypt remote looks like

$ rclone -q ls remote:path
       55 hagjclgavj2mbiqm6u6cnjjqcg
       54 v05749mltvv1tf4onltun46gls
       57 86vhrsv86mpbtd3a0akjuqslj8/dlj7fkq4kdq72emafg7a7s41uo
       58 86vhrsv86mpbtd3a0akjuqslj8/7uu829995du6o42n32otfhjqp4/b9pausrfansjth5ob3jkdqd4lc
       56 86vhrsv86mpbtd3a0akjuqslj8/8njh1sk437gttmep3p70g81aps

The directory structure is preserved

$ rclone -q ls secret:subdir
        8 file2.txt
        9 file3.txt
       10 subsubdir/file4.txt

Without file name encryption .bin extensions are added to underlying names. This prevents the cloud provider attempting to interpret file content.

$ rclone -q ls remote:path
       54 file0.txt.bin
       57 subdir/file3.txt.bin
       56 subdir/file2.txt.bin
       58 subdir/subsubdir/file4.txt.bin
       55 file1.txt.bin

文件名加密模式

关闭加密(Off)

  • 不隐藏文件名和目录结构
  • 允许使用较长的文件名(约246个字符)
  • 可以使用子路径并复制单个文件

标准加密(Standard)

  • 文件名被加密
  • 文件名不能太长(约143个字符)
  • 可以使用子路径并复制单个文件
  • 目录结构可见
  • 相同的文件名上传后会保持一致
  • 可以使用快捷方式缩短目录递归

模糊处理(Obfuscation)

这是一种简单的文件名“旋转”方法,每个文件的旋转距离基于文件名确定。Rclone会将这个距离存储在文件名的开头。例如,名为“hello”的文件可能会变成“53.jgnnq”。

模糊处理并非强大的文件名加密方式,但可以阻碍自动化扫描工具识别文件名模式。它介于“关闭加密”和“标准加密”之间,允许使用较长的路径段名称。

对于某些基于Unicode的文件名,模糊处理可能效果不佳,可能会将小写字符映射为大写字符。

模糊处理不能提供强大的保护。

  • 文件名经过轻度模糊处理
  • 文件名可以比标准加密方式下更长
  • 可以使用子路径并复制单个文件
  • 目录结构可见
  • 相同的文件名上传后会保持一致

云存储系统对文件名长度和总路径长度有限制,使用“标准”文件名加密时,Rclone更有可能超出这些限制。无论使用哪种云存储提供商,只要文件名长度不超过143个字符,通常不会遇到问题。

现在提供了一个实验性的高级选项 filename_encoding 来在一定程度上解决这个问题。 对于区分大小写文件名的云存储系统(如Google Drive),可以使用 base64 来缩短文件名长度。 对于内部使用UTF - 16存储文件名的云存储系统(如OneDrive、Dropbox、Box),可以使用 base32768 来大幅缩短文件名长度。

未来,Rclone可能会推出一种新的文件名加密模式,以适应后端提供商的路径长度限制。

目录名加密

Crypt提供了加密目录名或保持其原样的选项。有两个选项:

加密(True)

对包括目录名在内的整个文件路径进行加密。 示例: 1/12/123.txt 加密后变为 p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0

不加密(False)

仅加密文件名,跳过目录名。 示例: 1/12/123.txt 加密后变为 1/12/qgm4avr35m5loi1th53ato71v0

修改时间和哈希值

Crypt使用底层远程存储来存储修改时间,因此是否支持取决于底层远程存储。

Crypt不存储哈希值。但是,数据完整性由一个非常强大的加密认证器保护。

使用 rclone cryptcheck 命令来检查加密远程存储的完整性,而不是使用 rclone check,因为后者无法正确检查校验和。

标准选项

以下是Crypt(对远程存储进行加密/解密)特定的标准选项。

–crypt-remote

要加密/解密的远程存储。

通常应包含 : 和路径,例如 “myremote:path/to/dir”、“myremote:bucket” 或者 “myremote:"(不推荐)。

属性:

  • 配置项:remote
  • 环境变量:RCLONE_CRYPT_REMOTE
  • 类型:字符串
  • 是否必需:是

–crypt-filename-encryption

如何加密文件名。

属性:

  • 配置项:filename_encryption
  • 环境变量:RCLONE_CRYPT_FILENAME_ENCRYPTION
  • 类型:字符串
  • 默认值:“standard”
  • 示例:
    • “standard”
      • 加密文件名。
      • 详情请参阅文档。
    • “obfuscate”
      • 非常简单的文件名模糊处理。
    • “off”
      • 不加密文件名。
      • 仅添加 “.bin” 或 “suffix” 扩展名。

–crypt-directory-name-encryption

是否加密目录名或保持其原样的选项。

注意:如果 filename_encryption 为 “off”,则此选项无效。

属性:

  • 配置项:directory_name_encryption
  • 环境变量:RCLONE_CRYPT_DIRECTORY_NAME_ENCRYPTION
  • 类型:布尔值
  • 默认值:true
  • 示例:
    • “true”
      • 加密目录名。
    • “false”
      • 不加密目录名,保持其原样。

–crypt-password

加密用的密码或密码短语。

注意:输入此选项的值必须进行混淆处理 - 请参阅 rclone obscure

属性:

  • 配置项:password
  • 环境变量:RCLONE_CRYPT_PASSWORD
  • 类型:字符串
  • 是否必需:是

–crypt-password2

用于盐的密码或密码短语。

可选但推荐使用。 应与之前的密码不同。

注意:输入此选项的值必须进行混淆处理 - 请参阅 rclone obscure

属性:

  • 配置项:password2
  • 环境变量:RCLONE_CRYPT_PASSWORD2
  • 类型:字符串
  • 是否必需:否

高级选项

以下是Crypt(对远程存储进行加密/解密)特定的高级选项。

–crypt-server-side-across-configs

已弃用:请使用 --server-side-across-configs 代替。

允许跨不同的Crypt配置进行服务器端操作(例如复制)。

通常情况下,你可能不需要此选项,但如果你有两个指向同一后端的Crypt配置,可以使用它。

例如,你可以使用此选项在不重新上传所有数据的情况下更改文件名加密类型。只需创建两个指向不同目录的Crypt后端,仅更改一个参数,然后使用 rclone move 在两个Crypt远程存储之间移动文件。

属性:

  • 配置项:server_side_across_configs
  • 环境变量:RCLONE_CRYPT_SERVER_SIDE_ACROSS_CONFIGS
  • 类型:布尔值
  • 默认值:false

–crypt-show-mapping

列出所有文件时显示文件名的加密映射。

如果设置了此标志,当远程存储被要求列出文件时,它将在INFO级别记录一行,说明解密后的文件名和加密后的文件名。

这样,你可以确定哪些加密文件名对应哪些解密文件名,以防你需要对加密文件名进行操作,或者用于调试目的。

属性:

  • 配置项:show_mapping
  • 环境变量:RCLONE_CRYPT_SHOW_MAPPING
  • 类型:布尔值
  • 默认值:false

–crypt-no-data-encryption

是否对文件数据进行加密或保持其未加密的选项。

属性:

  • 配置项:no_data_encryption
  • 环境变量:RCLONE_CRYPT_NO_DATA_ENCRYPTION
  • 类型:布尔值
  • 默认值:false
  • 示例:
    • “true”
      • 不加密文件数据,保持其未加密状态。
    • “false”
      • 加密文件数据。

–crypt-pass-bad-blocks

如果设置,将把损坏的块当作全0处理。

在正常操作中不应设置此选项,仅在尝试恢复有错误的加密文件并希望尽可能多地恢复文件内容时才应设置。

属性:

  • 配置项:pass_bad_blocks
  • 环境变量:RCLONE_CRYPT_PASS_BAD_BLOCKS
  • 类型:布尔值
  • 默认值:false

–crypt-strict-names

如果设置,当Crypt遇到无法解密的文件名时将引发错误。

(默认情况下,Rclone只会记录一条通知并正常继续。)如果加密和未加密的文件存储在同一目录中(不推荐这样做),可能会出现这种情况。这也可能表明存在更严重的问题,需要进行调查。

属性:

  • 配置项:strict_names
  • 环境变量:RCLONE_CRYPT_STRICT_NAMES
  • 类型:布尔值
  • 默认值:false

–crypt-filename-encoding

如何将加密后的文件名编码为文本字符串。

此选项有助于缩短加密后的文件名。合适的选项取决于你的远程存储计算文件名长度的方式以及是否区分大小写。

属性:

  • 配置项:filename_encoding
  • 环境变量:RCLONE_CRYPT_FILENAME_ENCODING
  • 类型:字符串
  • 默认值:“base32”
  • 示例:
    • “base32”
      • 使用Base32编码。适用于所有远程存储。
    • “base64”
      • 使用Base64编码。适用于区分大小写的远程存储。
    • “base32768”
      • 使用Base32768编码。适用于远程存储使用UTF - 16或Unicode码点而不是UTF - 8字节长度来计算文件名长度的情况(例如OneDrive、Dropbox)。

–crypt-suffix

如果设置,将覆盖默认的 “.bin” 扩展名。

将后缀设置为 “none” 将导致后缀为空。当路径长度很关键时,这可能会很有用。

属性:

  • 配置项:suffix
  • 环境变量:RCLONE_CRYPT_SUFFIX
  • 类型:字符串
  • 默认值:".bin”

–crypt-description

远程存储的描述。

属性:

  • 配置项:description
  • 环境变量:RCLONE_CRYPT_DESCRIPTION
  • 类型:字符串
  • 是否必需:否

元数据

底层远程存储支持的任何元数据都会被读取和写入。

有关更多信息,请参阅 元数据 文档。

后端命令

以下是Crypt后端特定的命令。

使用以下命令运行它们:

rclone backend COMMAND remote:

下面的帮助信息将解释每个命令需要哪些参数。

有关如何传递选项和参数的更多信息,请参阅 backend 命令。

这些命令可以在运行的后端上使用rc命令 backend/command 执行。

encode

对给定的文件名进行编码

rclone backend encode remote: [options] [<arguments>+]

此命令对作为参数给出的文件名进行编码,并返回编码结果的字符串列表。

使用示例:

rclone backend encode crypt: file1 [file2...]
rclone rc backend/command command=encode fs=crypt: file1 [file2...]

decode

对给定的文件名进行解码

rclone backend decode remote: [options] [<arguments>+]

此命令对作为参数给出的文件名进行解码,并返回解码结果的字符串列表。如果任何输入无效,将返回错误。

使用示例:

rclone backend decode crypt: encryptedfile1 [encryptedfile2...]
rclone rc backend/command command=decode fs=crypt: encryptedfile1 [encryptedfile2...]

备份加密远程存储

如果你希望备份加密的远程存储,建议对加密文件使用 rclone sync,并确保新的加密远程存储中的密码相同。

这样做有以下优点:

  • rclone sync 在复制时会检查校验和
  • 你可以在加密的远程存储之间使用 rclone check
  • 你不会不必要地进行解密和加密操作

例如,假设你有一个原始远程存储 remote:,其加密版本为 eremote:,路径为 remote:crypt。你可以设置一个新的远程存储 remote2:,然后使用与 eremote: 相同的密码创建加密版本 eremote2:,路径为 remote2:crypt

要同步这两个远程存储,你可以执行以下命令:

rclone sync --interactive remote:crypt remote2:crypt

要检查完整性,你可以执行以下命令:

rclone check remote:crypt remote2:crypt

文件格式

文件加密

文件以 1:1 的方式从源文件加密到目标对象。文件有一个头部,并被分割成块。

头部

  • 8 字节的魔术字符串 RCLONE\x00\x00
  • 24 字节的随机数(IV)

初始随机数由操作系统的强加密随机数生成器生成。每个读取的块的随机数都会递增,确保每个写入的块的随机数都是唯一的。重复使用随机数的可能性极小。如果你写入了 1 EB(10¹⁸ 字节)的数据,重复使用随机数的概率约为 2×10⁻³²。

每个块将包含 64 KiB 的数据,除了最后一个块可能包含较少的数据。数据块采用标准的NaCl SecretBox格式。SecretBox使用XSalsa20和Poly1305来加密和验证消息。

每个块包含:

  • 16 字节的Poly1305认证器
  • 1 - 65536 字节的XSalsa20加密数据

选择 64k 的块大小是因为它是性能最佳的块大小(低于此大小,认证器会花费过多时间;高于此大小,由于缓存效应,性能会下降)。请注意,这些块会缓存在内存中,因此不能太大。

这使用了一个从用户密码派生的 32 字节(256 位密钥)的密钥。

示例

1 字节的文件将加密为:

  • 32 字节的头部
  • 17 字节的数据块

总共 49 字节

1 MiB(1048576 字节)的文件将加密为:

  • 32 字节的头部
  • 16 个 65568 字节的块

总共 1049120 字节(开销为 0.05%)。这是大文件的开销。

名称加密

文件名按段进行加密 - 路径被分割成以 / 分隔的字符串,然后分别对这些字符串进行加密。

文件段在加密前使用PKCS#7填充到 16 字节的倍数。

然后使用AES 256位密钥通过EME进行加密。EME(ECB - Mix - ECB)是Halevi和Rogaway在2003年的论文 “A Parallelizable Enciphering Mode” 中提出的一种宽块加密模式。

这使得加密具有确定性,这正是我们所需要的 - 相同的文件名必须加密为相同的结果,否则我们无法在云存储系统中找到它。

这意味着:

  • 相同的文件名加密后结果相同
  • 开头相同的文件名不会有共同的前缀

这使用了一个 32 字节的密钥(256 位)和一个 16 字节(128 位)的随机数,两者都从用户密码派生。

加密后,它们使用RFC4648中描述的标准 base32 编码的修改版本进行输出。标准编码有两处修改:

  • 变为小写(没有人喜欢大写文件名!)
  • 去除填充字符 =

使用 base32 而不是更高效的 base64,以便Rclone可以在不区分大小写的远程存储(如Windows、Box、Dropbox、OneDrive等)上使用。

密钥派生

Rclone使用 scrypt,参数为 N = 16384, r = 8, p = 1,并可选择用户提供的盐(password2)来派生所需的 32 + 32 + 16 = 80 字节的密钥材料。如果用户没有提供盐,Rclone将使用内部的盐。

scrypt 使得对Rclone加密数据进行字典攻击变得不切实际。为了全面防范此类攻击,你应该始终使用盐。

另请参阅