回答編集履歴

11

zip

2016/11/06 10:51

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -78,21 +78,9 @@
78
78
 
79
79
  def secure_compare(a, b)
80
80
 
81
- if a.length != b.length
81
+ a.bytesize == b.bytesize &&
82
82
 
83
- return false
84
-
85
- end
86
-
87
- result = 0
88
-
89
- a.length.times do |i|
90
-
91
- result |= a[i].ord ^ b[i].ord
83
+ a.bytes.zip(b.bytes).map{|x,y| x^y}.reduce(&:|) == 0
92
-
93
- end
94
-
95
- result == 0
96
84
 
97
85
  end
98
86
 

10

Rubyistっぽく

2016/11/06 10:51

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -40,7 +40,7 @@
40
40
 
41
41
  hmac = hmac_encode(value)
42
42
 
43
- return Base64.urlsafe_encode64(value + hmac).gsub('=', '')
43
+ Base64.urlsafe_encode64(value + hmac).gsub('=', '')
44
44
 
45
45
  end
46
46
 
@@ -62,11 +62,11 @@
62
62
 
63
63
  if !secure_compare(hmac_encode(value), hmac)
64
64
 
65
- raise RuntimeError.new('invalid signature')
65
+ raise RuntimeError, 'invalid signature'
66
66
 
67
67
  end
68
68
 
69
- return cipher.update(value) + cipher.final
69
+ cipher.update(value) + cipher.final
70
70
 
71
71
  end
72
72
 
@@ -92,7 +92,7 @@
92
92
 
93
93
  end
94
94
 
95
- return result == 0
95
+ result == 0
96
96
 
97
97
  end
98
98
 
@@ -100,7 +100,7 @@
100
100
 
101
101
  def hmac_encode(value)
102
102
 
103
- return Base64.urlsafe_encode64(OpenSSL::HMAC.digest('sha256', @hmac, value)).gsub('=', '')
103
+ Base64.urlsafe_encode64(OpenSSL::HMAC.digest('sha256', @hmac, value)).gsub('=', '')
104
104
 
105
105
  end
106
106
 

9

update

2016/11/06 10:23

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -62,7 +62,7 @@
62
62
 
63
63
  if !secure_compare(hmac_encode(value), hmac)
64
64
 
65
- raise OpenSSL::Cipher::CipherError.new('invalid signature')
65
+ raise RuntimeError.new('invalid signature')
66
66
 
67
67
  end
68
68
 

8

=の削除

2016/11/06 10:20

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -40,7 +40,7 @@
40
40
 
41
41
  hmac = hmac_encode(value)
42
42
 
43
- return Base64.urlsafe_encode64(value + hmac)
43
+ return Base64.urlsafe_encode64(value + hmac).gsub('=', '')
44
44
 
45
45
  end
46
46
 
@@ -55,10 +55,6 @@
55
55
  cipher.key = @key
56
56
 
57
57
  cipher.iv = @iv
58
-
59
- # ↓ Fuelのほうはこれやってるけど不必要な可能性大
60
-
61
- # value << '=' * ((4 - value.length % 4) % 4)
62
58
 
63
59
  value = Base64.urlsafe_decode64(value)
64
60
 

7

例外型にした

2016/11/04 01:33

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -66,7 +66,7 @@
66
66
 
67
67
  if !secure_compare(hmac_encode(value), hmac)
68
68
 
69
- return false
69
+ raise OpenSSL::Cipher::CipherError.new('invalid signature')
70
70
 
71
71
  end
72
72
 

6

不必要?

2016/11/03 23:05

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -56,7 +56,9 @@
56
56
 
57
57
  cipher.iv = @iv
58
58
 
59
+ # ↓ Fuelのほうはこれやってるけど不必要な可能性大
60
+
59
- value << '=' * ((4 - value.length % 4) % 4)
61
+ # value << '=' * ((4 - value.length % 4) % 4)
60
62
 
61
63
  value = Base64.urlsafe_decode64(value)
62
64
 

5

更新

2016/11/03 22:58

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -1,12 +1,4 @@
1
- # 更新
2
-
3
-
4
-
5
- よく考えら16バイト固定長鍵なの,`key_len`を操作する意味はありませんでしたね,失礼しました。回答を一次撤回します。ちょっとPHPSecLibソースを追るだけ追ってみます
1
+ 解決したので回答を更新します。これでFuel互換暗号化と復号が行えます
6
-
7
-
8
-
9
- crypt.phpの[PHPSecLibを呼び出している場所](https://github.com/fuel/core/blob/1.9/develop/classes/crypt.php#L247)に base64_encode + var_dump を入れてチェックしてみたのですが,この時点で
10
2
 
11
3
 
12
4
 
@@ -24,11 +16,11 @@
24
16
 
25
17
  def initialize(key, iv, hmac)
26
18
 
27
- @key = key
19
+ @key = Base64.urlsafe_decode64(key)
28
20
 
29
- @iv = iv
21
+ @iv = Base64.urlsafe_decode64(iv)
30
22
 
31
- @hmac = hmac
23
+ @hmac = Base64.urlsafe_decode64(hmac)
32
24
 
33
25
  end
34
26
 
@@ -38,19 +30,79 @@
38
30
 
39
31
  cipher = OpenSSL::Cipher.new('aes-128-cbc')
40
32
 
33
+ cipher.encrypt
34
+
41
35
  cipher.key = @key
42
36
 
43
37
  cipher.iv = @iv
44
38
 
45
- cipher.encrypt
46
-
47
39
  value = cipher.update(value) + cipher.final
48
40
 
49
- p Base64.encode64(value) # => ここで確認
41
+ hmac = hmac_encode(value)
50
-
51
- hmac = Base64.urlsafe_encode64(OpenSSL::HMAC.digest('sha256', @hmac, value)).gsub('=', '')
52
42
 
53
43
  return Base64.urlsafe_encode64(value + hmac)
44
+
45
+ end
46
+
47
+
48
+
49
+ def decode(value)
50
+
51
+ cipher = OpenSSL::Cipher.new('aes-128-cbc')
52
+
53
+ cipher.decrypt
54
+
55
+ cipher.key = @key
56
+
57
+ cipher.iv = @iv
58
+
59
+ value << '=' * ((4 - value.length % 4) % 4)
60
+
61
+ value = Base64.urlsafe_decode64(value)
62
+
63
+ hmac = value.slice!(-43, 43)
64
+
65
+ if !secure_compare(hmac_encode(value), hmac)
66
+
67
+ return false
68
+
69
+ end
70
+
71
+ return cipher.update(value) + cipher.final
72
+
73
+ end
74
+
75
+
76
+
77
+ private
78
+
79
+
80
+
81
+ def secure_compare(a, b)
82
+
83
+ if a.length != b.length
84
+
85
+ return false
86
+
87
+ end
88
+
89
+ result = 0
90
+
91
+ a.length.times do |i|
92
+
93
+ result |= a[i].ord ^ b[i].ord
94
+
95
+ end
96
+
97
+ return result == 0
98
+
99
+ end
100
+
101
+
102
+
103
+ def hmac_encode(value)
104
+
105
+ return Base64.urlsafe_encode64(OpenSSL::HMAC.digest('sha256', @hmac, value)).gsub('=', '')
54
106
 
55
107
  end
56
108
 
@@ -70,36 +122,20 @@
70
122
 
71
123
  )
72
124
 
73
- puts crypt.encode('テストテスト')
74
125
 
126
+
75
- ```
127
+ plain = 'テストテスト'
128
+
129
+ encoded = crypt.encode(plain)
130
+
131
+ p encoded # => "yIrEuHGvDsLoCsm0UMBw9r4BjpfikN1Ob4bPmA-qcfpWRkY0ZmtRZmM4OWdwanh6OG8xTzBLcF9abTlpMGRTWmF5WVI5THBZOFYw"
76
132
 
77
133
 
78
134
 
79
- から得られる結果とは全く違います…うーん…
135
+ decoded = crypt.decode(encoded)
80
136
 
137
+ p decoded # => "\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88"
81
138
 
82
-
83
-
84
-
85
- # 古い回答
86
-
87
-
88
-
89
- 何となくこれと同じ問題のような気がします…
90
-
91
-
92
-
93
- [PHP - PHPとRubyでBlowfishを使って全く同じ暗号化を行いたい(53617)|teratail](https://teratail.com/questions/53617)
139
+ p decoded.force_encoding('utf-8') # => "テストテスト"
94
-
95
-
96
-
97
- ```ruby
98
-
99
- dec.key_len = pass.bytesize
100
140
 
101
141
  ```
102
-
103
-
104
-
105
- これを入れてください。

4

a

2016/11/03 22:55

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
 
8
8
 
9
- crypt.phpの[PHPSecLibを呼び出している場所](https://github.com/fuel/core/blob/1.9/develop/classes/crypt.php#L247)にvar_dumpを入れてチェックしてみたのですが,この時点で
9
+ crypt.phpの[PHPSecLibを呼び出している場所](https://github.com/fuel/core/blob/1.9/develop/classes/crypt.php#L247)に base64_encode + var_dump を入れてチェックしてみたのですが,この時点で
10
10
 
11
11
 
12
12
 

3

更新

2016/11/03 11:08

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -3,6 +3,82 @@
3
3
 
4
4
 
5
5
  よく考えたら16バイト固定長の鍵なので,`key_len`を操作する意味はありませんでしたね,失礼しました。回答を一次撤回します。ちょっとPHPSecLibのソースを追えるだけ追ってみます…
6
+
7
+
8
+
9
+ crypt.phpの[PHPSecLibを呼び出している場所](https://github.com/fuel/core/blob/1.9/develop/classes/crypt.php#L247)にvar_dumpを入れてチェックしてみたのですが,この時点で
10
+
11
+
12
+
13
+ ```ruby
14
+
15
+ require 'openssl'
16
+
17
+ require 'base64'
18
+
19
+
20
+
21
+ class FuelCrypter
22
+
23
+
24
+
25
+ def initialize(key, iv, hmac)
26
+
27
+ @key = key
28
+
29
+ @iv = iv
30
+
31
+ @hmac = hmac
32
+
33
+ end
34
+
35
+
36
+
37
+ def encode(value)
38
+
39
+ cipher = OpenSSL::Cipher.new('aes-128-cbc')
40
+
41
+ cipher.key = @key
42
+
43
+ cipher.iv = @iv
44
+
45
+ cipher.encrypt
46
+
47
+ value = cipher.update(value) + cipher.final
48
+
49
+ p Base64.encode64(value) # => ここで確認
50
+
51
+ hmac = Base64.urlsafe_encode64(OpenSSL::HMAC.digest('sha256', @hmac, value)).gsub('=', '')
52
+
53
+ return Base64.urlsafe_encode64(value + hmac)
54
+
55
+ end
56
+
57
+
58
+
59
+ end
60
+
61
+
62
+
63
+ crypt = FuelCrypter.new(
64
+
65
+ '9eEBP8okkcz4xAo9rU5h4f7Q',
66
+
67
+ 'HncqRUWjEl2Y53sqawnK4Y7Q',
68
+
69
+ 'ra4OxkVxYthofVMlAk0ncQrQ',
70
+
71
+ )
72
+
73
+ puts crypt.encode('テストテスト')
74
+
75
+ ```
76
+
77
+
78
+
79
+ から得られる結果とは全く違います…うーん…
80
+
81
+
6
82
 
7
83
 
8
84
 

2

typo

2016/11/03 11:07

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- よく考えたら16バイト固定長の鍵なので,`key_len`を操作する意味はありませんでしたね,失礼しました。回答を一次撤回します。ちょっとPHPSpecLibのソースを追えるだけ追ってみます…
5
+ よく考えたら16バイト固定長の鍵なので,`key_len`を操作する意味はありませんでしたね,失礼しました。回答を一次撤回します。ちょっとPHPSecLibのソースを追えるだけ追ってみます…
6
6
 
7
7
 
8
8
 

1

訂正

2016/11/03 08:20

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -1,3 +1,15 @@
1
+ # 更新
2
+
3
+
4
+
5
+ よく考えたら16バイト固定長の鍵なので,`key_len`を操作する意味はありませんでしたね,失礼しました。回答を一次撤回します。ちょっとPHPSpecLibのソースを追えるだけ追ってみます…
6
+
7
+
8
+
9
+ # 古い回答
10
+
11
+
12
+
1
13
  何となくこれと同じ問題のような気がします…
2
14
 
3
15