更新时间:2023-07-25 GMT+08:00

加密传输与存储

代码托管服务通过使用git-crypt来满足开发者对机密、敏感文件的加密存储与传输需要。

git-crypt简介

git-crypt是一款第三方开源软件,可以用于对Git仓库中的文件进行透明化的加密和解密。其可对指定文件、指定文件类型等进行加密存储,开发者可以将加密文件(如机密信息或敏感数据)与可共享的代码存储在同一个仓库中,并如同普通仓库一样被拉取和推送,只有持有对应文件密钥的人才能查看到加密文件的内容,但并不会限制参与者对非加密文件读写。

也就是说,使用git-crypt可以让您仅加密特定文件,而不需要锁定整个仓库,这既方便了团队合作,又可兼顾信息安全。

在Windows中使用密钥对方式进行加密、解密

  1. 安装并初始化Git。
  2. 下载最新基于Windows的git-crypt,将下载到的exe文件放到Git安装目录下的“cmd”文件夹中,下图以“Windows Server 2012 R2 标准版 64”的默认Git Bash安路径为例。

    放进文件夹即可,不需要运行此exe。

  3. 生成密钥对

    1. 打开“Git Bash”,并进入本地仓库(如下图①)。
    2. 生成密钥对,输入指令如下(如下图②):
      git-crypt init
    3. 将密钥文件导出,本示例中将密钥文件导出到C:\test目录并名为KeyFile,输入指令如下(如下图③):
      git-crypt export-key /c/test/keyfile

    4. 执行完以上步骤,可以到密钥导出的文件路径,验证下是否生成了密钥,本示例中通过C:\test路径验证是否有KeyFile文件,如下图所示。

      持有这个密钥文件的计算机,可以解密对应的加密文件。

  4. 为仓库配置加密范围

    1. 在仓库的根目录下新建一个名为.gitattributes的文件。
    2. 打开.gitattributes文件,设置加密范围,语法如下。
      文件名或文件范围 filter=git-crypt diff=git-crypt
      下面给出四个示例。
      FT/file01.txt filter=git-crypt diff=git-crypt   #将 特定文件加密,这里加密的是FT文件夹下的file01.txt
      *.java filter=git-crypt diff=git-crypt   #将 .java类型文件加密
      G* filter=git-crypt diff=git-crypt       #将 文件名为 G 开头的文件加密
      ForTest/** filter=git-crypt diff=git-crypt #将 ForTest 文件夹下的文件加密 

    • 如果创建.gitattributes文件时提示“必须键入文件名”,可以将文件名填写成 “.gitattributes.”即可创建成功,如果使用Linux指令创建文件,则不会出现此问题。
    • 注意不要将.gitattributes保存成txt文件,这样配置会无效。

  5. 进行文件加密

    仓库根目录打开Git bash,执行如下指令即可完成加密,并会看到目前文件的加密状态。

    git-crypt status

    加密执行后,在您的本地仓库仍能明文方式打开和编辑这些加密文件,这是因为您本地仓库有密钥存在。

    这时你可以使用add 、commit、push组合将仓库推送到云端,此时加密文件将一同被推送。

    加密文件在云端仓库中将以加密二进制方式存储,无法直接查看。如果没有密钥,就算将其下载到本地,也无法解密。

    “git-crypt status”只会加密本次待提交的文件,对本次未发生修改的历史文件不会产生加密作用,Git会对此设定涉及的未加密文件做出提示(见上图中的Warning),如果想将仓库中的对应类型文件全部加密,请使用“git-crypt status -f”

    在让团队合作中 -f (强制执行)具有一定的风险,可能会对合作伙伴的工作产生不变,请谨慎使用。

  6. 进行文件解密

    1. 确认本机器Git安装路径下存在git-crypt文件。

    2. 将仓库从云端克隆到本地。
    3. 获取加密此仓库的密钥文件,并存储于本地计算机。

    4. 进入仓库目录,右键打开Git bash。
    5. 执行解密指令,执行后无回显,则为执行成功。
      git-crypt unlock /C/test/KeyFile     #请将 /C/test/KeyFile 更换为您实际的密钥存储路径

      以此案例中加密的Git001.txt为例,解密前、解密后的查看效果分别如下。

      图1 解密前
      图2 解密后

在Windows中使用GPG方式进行加密、解密

  1. 安装并初始化Git。
  2. 下载最新基于Windows的git-crypt,将下载到的exe文件放到Git安装目录下的“cmd”文件夹中,下图以“Windows Server 2012 R2 标准版 64”的默认Git Bash安路径为例。

    放进文件夹即可,不需要运行此exe。

  3. 下载GPG最新版本,当提示您捐赠此开源软件时,选“0”,即可跳过捐赠环节。

    双击进行安装,仅使用“下一步”,即可完成安装。

  4. 使用GPG方式生成密钥对

    1. 任意位置打开Git Bash,执行如下指令。
      gpg --gen-key
    2. 根据提示,输入名称、邮箱。

    3. 确认无误后,按提示输入 “o”,并回车,此时会弹出输入密码窗口和确认密码窗口。

      密码可以为空,出于信息安全考虑,建议输入符合标准的密码(解密时需要这个密码)。

    4. 出现如下图返回内容,则为GPG密钥对生成成功。

  5. 进行仓库加密初始化设置

    1. 仓库根目录打开Git bash,执行如下指令进行初始化。
      git-crypt init

    2. 将密钥副本添加到您的仓库,该副本已使用您的公共GPG密钥加密,指令如下。
      git-crypt add-gpg-user USER_ID

      此处的“USER_ID”可以是生成此密钥时的名称(①)、邮箱(②)或指纹(③)这三种可以唯一标识此密钥的东西。

      执行后会提示您创建了.git-crypt文件夹以及其中的两个文件。

  6. 为仓库配置加密范围

    1. 进入仓库下的.git-crypt文件夹。
    2. 打开.gitattributes文件,设置加密范围,语法如下。
      文件名或文件范围 filter=git-crypt diff=git-crypt
      下面给出四个示例。
      FT/file01.txt filter=git-crypt diff=git-crypt   #将 特定文件加密,这里加密的是FT文件夹下的file01.txt
      *.java filter=git-crypt diff=git-crypt   #将 .java类型文件加密
      G* filter=git-crypt diff=git-crypt       #将 文件名为 G 开头的文件加密
      ForTest/** filter=git-crypt diff=git-crypt #将 ForTest 文件夹下的文件加密 

    3. 将.gitattributes文件复制到仓库的根目录下。

  7. 进行文件加密

    仓库根目录打开Git bash,执行如下指令即可完成加密,并会看到目前文件的加密状态。

    git-crypt status

    加密执行后,在您的本地仓库仍能明文方式打开和编辑这些加密文件,这是因为您本地仓库有密钥存在。

    这时你可以使用add 、commit、push组合将仓库推送到云端,此时加密文件将一同被推送。

    加密文件在云端仓库中将以加密二进制方式存储,无法直接查看。如果没有密钥,就算将其下载到本地,也无法解密。

    “git-crypt status”只会加密本次待提交的文件,对本次未发生修改的历史文件不会产生加密作用,Git会对此设定涉及的未加密文件做出提示(见上图中的Warning),如果想将仓库中的对应类型文件全部加密,请使用“git-crypt status -f”

    在让团队合作中 -f (强制执行)具有一定的风险,可能会对合作伙伴的工作产生不变,请谨慎使用。

  8. 将密钥导出

    1. 列出当前可见密钥,可以看到每个密钥的名称、邮箱、指纹信息。
      gpg --list-keys

    2. 使用gpg --export-secret-key指令导出密钥,本示例中将名称为“gpgTest”的密钥导出到“C盘”,并命名为“Key”
      gpg --export-secret-key -a gpgTest > /c/key    # -a 代表以 文本形式显示输出

      执行时会提示您输出次密钥的密码,正确输入即可。

      执行后无回显,到对应目录(本示例中为C盘)可看到密钥文件。

    3. 将生成的密钥发送给团队内需要共享秘密文件的伙伴。

  9. 将密钥导入并解密文件

    1. 想要在另一台机器解密文件,首先也需要基于Git,下载安装git-crypt、GPG,可以参考本文前几步骤的操作。
    2. 将对应仓库Clone到本地。
    3. 取得对应加密文件的密钥,密钥的导出请参见上一步骤,本示例中将取得的密钥放在C盘。
    4. 进入仓库,打开Git Bash使用import指令导入密钥。
      gpg --import  /c/key
      #其中 /c/Key 是本示例的密钥路径和密钥自定义名称,实际使用时,请根据实际情况替换

      导入时会弹出按提示您输入此密钥的密码,导入成功会的效果如下图。

    5. 使用unlock指令,解密文件。
      git-crypt unlock

      解锁时会弹窗提示您输入此密钥的密码,正确输入后无回显,则为解锁成功。

  10. 解密完成后,查看文件可以看到文件内容已经不是加密状态。

    图3 解密前
    图4 解密后

git-crypt加密在团队合作中的应用

在很多时候,团队需要在代码仓库中存储限制公开的文件,这时可以优先考虑使用“CodeHub” + “Git” + “git-crypt”的组合,来实现部分文件在仓库分布式开源中的加密。

通常,直接使用密钥对方式的加密就能满足限制部分文件访问的需要。

当团队需要将加密文件设置不同的秘密级别时,可以使用GPG方式加密,这种方式支持用户对同一个仓库的不同文件使用不同的密钥加密,将不同密级的密钥分别随仓库共享给组织内的伙伴,即可实现文件的定向分级限制访问。

Linux、Mac平台的git-crypt、gpg安装

Linux平台安装git-crypt、gpg

  • Linux安装依赖环境。

    Software

    Debian/Ubuntu package

    RHEL/CentOS package

    Make

    make

    make

    A C++11 compiler (e.g. gcc 4.9+)

    g++

    gcc-c++

    OpenSSL development files

    libssl-dev

    openssl-devel

  • Linux环境下,使用源码编译方式安装git-crypt。

    下载源码

    make
    make install

    安装到指定目录。

    make install PREFIX=/usr/local
  • Linux环境下,使用源码编译方式安装GPG。

    下载源码

    ./configure
    make
    make install
  • 使用Debian包安装git-crypt。

    下载源码

    Debian打包可以在项目Git仓库的“debian”分支中找到。

    软件包是用“git-buildpackage”构建的,如下所示。

    git checkout debian
    git-buildpackage -uc -us
  • Debian环境下使用构建包安装GPG。
    sudo apt-get install gnupg

MAC平台安装git-crypt、gpg

  • macOS上安装git-crypt。

    使用 brew 软件包管理器,只需运行如下命令。

    brew install git-crypt
  • macOS上安装GPG。

    使用 brew 软件包管理器,只需运行如下命令。

    brew install gpg