ansible-vault の暗号処理について調べた

ansible_badge

ansible ではパスワードなど重要な情報を保全するために、ファイル単位で暗号化する ansible-vault というコマンドがある。
この暗号方式について調べたのでメモ。

3行でまとめると

暗号処理の流れ

ansible-vault-encrypt

0. 前提

インプットとしては

  • 暗号化するファイル
  • ユーザーが入力したパスワード

がある

1. salt の生成

/dev/urandomsalt を生成

2. 暗号鍵 の生成

  • salt
  • パスワード

をもとに、 PBKDF2 を使って暗号鍵を生成(ラウンド数は 10000, PRF は HMAC-SHA256)

この鍵を、

  • key1
  • key2
  • IV(nonce)

に分割

3. ファイルデータの暗号

  • key1
  • IV(をもとにした counter)
  • ファイルデータ(plain text)

を元に AES-CTR で暗号化(cipher text)

4. MAC 値の計算

  • key2
  • cipher text

を元に HMAC-SHA256 で MAC 値を計算

5. 暗号データの保存

  • salt
  • cipher text
  • MAC 値

をファイルに保存

復号処理の流れ

ansible-vault-decrypt

0. 前提

インプットとしては

  • 暗号化されたファイル
  • ユーザーが入力したパスワード

がある

1. 暗号データの読み取り

暗号化されたファイルを開いて

  • salt
  • cipher text
  • MAC 値

を読み取る

2. 暗号鍵 の生成

  • salt
  • パスワード

をもとに、 PBKDF2 を使って暗号鍵を生成(ラウンド数は 10000, , PRF は HMAC-SHA256)

この鍵を、

  • key1
  • key2
  • IV(nonce)

に分割

3. MAC 値の計算

  • key2
  • cipher text

を元に HMAC-SHA256 で MAC 値を計算

4. MAC 値の比較

  • 暗号されたファイルにある MAC 値
  • #3 の MAC値

を比較。一致していなければエラーとして復号処理を終了

5. ファイルデータの復号

  • key1
  • IV(をもとにした counter)
  • 暗号化されたファイルデータ(cipher text)

を元に AES-CTR で復号

ansible-vault の実行例

encrypt

$ cat foo.yml
---
- Apple
- Orange
$ ansible-vault encrypt foo.yml
Vault password:
Confirm Vault password:
Encryption successful
$ cat foo.yml
$ANSIBLE_VAULT;1.1;AES256
39363761393430663133353338643636633731323336306331356231363036666337393965316138
3939353561363664653330336662313135386464383665640a616432616537336631386335636233
38393034623537346230353066383638393638633232626339326164383363363531373532323938
3935363639663939340a333739353032373337636234393863376365333661336634633338653465
39633162323931343337316466376632323133636463383564313834343532633162
  • 1 行目は暗号形式
  • 2 行目以降は salt と MAC値とcipher text を一部加工しつつつなげたもの。

具体的には、2行目以降を以下のように Python から操作して salt/mac/cipher text を復元できる

>>> s = '''\
39363761393430663133353338643636633731323336306331356231363036666337393965316138
3939353561363664653330336662313135386464383665640a616432616537336631386335636233
38393034623537346230353066383638393638633232626339326164383363363531373532323938
3935363639663939340a333739353032373337636234393863376365333661336634633338653465
39633162323931343337316466376632323133636463383564313834343532633162'''
>>> from binascii import hexlify
>>> from binascii import unhexlify
>>> s.replace('\n', '')
'393637613934306631333533386436366337313233363063313562313630366663373939653161383939353561363664653330336662313135386464383665640a616432616537336631386335636233383930346235373462303530663836383936386332326263393261643833633635313735323239383935363639663939340a33373935303237333763623439386337636533366133663463333865346539633162323931343337316466376632323133636463383564313834343532633162'
>>> unhexlify(_)
'967a940f13538d66c712360c15b1606fc799e1a89955a66de303fb1158dd86ed\nad2ae73f18c5cb38904b574b050f868968c22bc92ad83c65175229895669f994\n379502737cb498c7ce36a3f4c38e4e9c1b2914371df7f2213cdc85d184452c1b'
>>> salt, mac, cipher = _.split('\n')
>>> salt = unhexlify(salt)
>>> cipher = unhexlify(cipher)
>>> salt
'\x96z\x94\x0f\x13S\x8df\xc7\x126\x0c\x15\xb1`o\xc7\x99\xe1\xa8\x99U\xa6m\xe3\x03\xfb\x11X\xdd\x86\xed'
>>> mac
'ad2ae73f18c5cb38904b574b050f868968c22bc92ad83c65175229895669f994'
>>> cipher
'7\x95\x02s|\xb4\x98\xc7\xce6\xa3\xf4\xc3\x8eN\x9c\x1b)\x147\x1d\xf7\xf2!<\xdc\x85\xd1\x84E,\x1b'

decrypt

$ ansible-vault decrypt foo.yml
Vault password: TYPE-WRONG-PASSWORD
ERROR: Decryption failed
$ ansible-vault decrypt foo.yml
Vault password:
Decryption successful
$ cat foo.yml
---
- Apple
- Orange

メモ

ソースコード

ansible-vault の暗号処理は ansible/utils/vault.py にある。

暗号ライブラリ

pycrypto を利用している。

PBKDF2

key derivation function の一種
Python 3.4 からは 標準ライブラリに含まれている
BlackBerry はラウンド数を 1 にしていて、問題を起こしたことがある

AES-CTR

pycrypt 2.7 からは AES-GCM(Galois Counter Mode) も対応予定する
https://github.com/dlitz/pycrypto/pull/45

あわせて読みたい

Advertisements
Tagged with: , , , ,
Posted in algorithm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
  • RT @__apf__: How to write a research paper: a guide for software engineers & practitioners. docs.google.com/presentation/d… /cc @inwyrd 4 months ago
  • RT @HayatoChiba: 昔、自然と対話しながら数学に打ち込んだら何かを悟れるのではと思いたち、専門書1つだけ持ってパワースポットで名高い奈良の山奥に1週間籠ったことがある。しかし泊まった民宿にドカベンが全巻揃っていたため、水島新司と対話しただけで1週間過ぎた。 それ… 5 months ago
  • RT @googlecloud: Ever wonder what underwater fiber optic internet cables look like? Look no further than this deep dive w/ @NatAndLo: https… 5 months ago
  • @ijin UTC+01:00 な時間帯で生活しています、、、 10 months ago
  • RT @mattcutts: Google's world-class Site Reliability Engineering team wrote a new book: amazon.com/Site-Reliabili… It's about managing produc… 1 year ago
%d bloggers like this: