root / extensions / bouncycastle / src / main / java / org / jclouds / encryption / bouncycastle / BouncyCastleEncryptionService.java @ 35e7942d
History | View | Annotate | Download (5.2 kB)
1 |
/**
|
---|---|
2 |
*
|
3 |
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
4 |
*
|
5 |
* ====================================================================
|
6 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
7 |
* you may not use this file except in compliance with the License.
|
8 |
* You may obtain a copy of the License at
|
9 |
*
|
10 |
* http://www.apache.org/licenses/LICENSE-2.0
|
11 |
*
|
12 |
* Unless required by applicable law or agreed to in writing, software
|
13 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
14 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15 |
* See the License for the specific language governing permissions and
|
16 |
* limitations under the License.
|
17 |
* ====================================================================
|
18 |
*/
|
19 |
package org.jclouds.encryption.bouncycastle; |
20 |
|
21 |
import java.io.ByteArrayOutputStream; |
22 |
import java.io.IOException; |
23 |
import java.io.InputStream; |
24 |
import java.io.OutputStream; |
25 |
import java.security.InvalidKeyException; |
26 |
import java.security.NoSuchAlgorithmException; |
27 |
import java.security.NoSuchProviderException; |
28 |
|
29 |
import javax.inject.Singleton; |
30 |
|
31 |
import org.bouncycastle.crypto.Digest; |
32 |
import org.bouncycastle.crypto.digests.MD5Digest; |
33 |
import org.bouncycastle.crypto.digests.SHA1Digest; |
34 |
import org.bouncycastle.crypto.digests.SHA256Digest; |
35 |
import org.bouncycastle.crypto.io.DigestOutputStream; |
36 |
import org.bouncycastle.crypto.macs.HMac; |
37 |
import org.bouncycastle.crypto.params.KeyParameter; |
38 |
import org.bouncycastle.util.encoders.Base64; |
39 |
import org.jclouds.encryption.internal.BaseEncryptionService; |
40 |
import org.jclouds.util.Utils; |
41 |
|
42 |
import com.google.common.io.Closeables; |
43 |
|
44 |
/**
|
45 |
*
|
46 |
* @author Adrian Cole
|
47 |
*/
|
48 |
@Singleton
|
49 |
public class BouncyCastleEncryptionService extends BaseEncryptionService { |
50 |
public String hmacSha256Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException, |
51 |
NoSuchProviderException, InvalidKeyException { |
52 |
Digest digest = new SHA256Digest();
|
53 |
return hmacBase64(toEncode, key, digest);
|
54 |
} |
55 |
|
56 |
private String hmacBase64(String toEncode, byte[] key, Digest digest) { |
57 |
byte[] resBuf = hmac(toEncode, key, digest); |
58 |
return toBase64String(resBuf);
|
59 |
} |
60 |
|
61 |
public byte[] hmac(String toEncode, byte[] key, Digest digest) { |
62 |
HMac hmac = new HMac(digest);
|
63 |
byte[] resBuf = new byte[hmac.getMacSize()]; |
64 |
byte[] plainBytes = Utils.encodeString(toEncode); |
65 |
byte[] keyBytes = key; |
66 |
hmac.init(new KeyParameter(keyBytes));
|
67 |
hmac.update(plainBytes, 0, plainBytes.length);
|
68 |
hmac.doFinal(resBuf, 0);
|
69 |
return resBuf;
|
70 |
} |
71 |
|
72 |
public String hmacSha1Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException, |
73 |
NoSuchProviderException, InvalidKeyException { |
74 |
Digest digest = new SHA1Digest();
|
75 |
return hmacBase64(toEncode, key, digest);
|
76 |
} |
77 |
|
78 |
public byte[] md5(byte[] plainBytes) { |
79 |
MD5Digest eTag = new MD5Digest();
|
80 |
byte[] resBuf = new byte[eTag.getDigestSize()]; |
81 |
eTag.update(plainBytes, 0, plainBytes.length);
|
82 |
eTag.doFinal(resBuf, 0);
|
83 |
return resBuf;
|
84 |
} |
85 |
|
86 |
public byte[] md5(InputStream toEncode) { |
87 |
MD5Digest eTag = new MD5Digest();
|
88 |
byte[] resBuf = new byte[eTag.getDigestSize()]; |
89 |
byte[] buffer = new byte[1024]; |
90 |
int numRead = -1; |
91 |
try {
|
92 |
do {
|
93 |
numRead = toEncode.read(buffer); |
94 |
if (numRead > 0) { |
95 |
eTag.update(buffer, 0, numRead);
|
96 |
} |
97 |
} while (numRead != -1); |
98 |
} catch (IOException e) { |
99 |
throw new RuntimeException(e); |
100 |
} finally {
|
101 |
Closeables.closeQuietly(toEncode); |
102 |
} |
103 |
eTag.doFinal(resBuf, 0);
|
104 |
return resBuf;
|
105 |
} |
106 |
|
107 |
public String toBase64String(byte[] resBuf) { |
108 |
return new String(Base64.encode(resBuf)); |
109 |
} |
110 |
|
111 |
public MD5InputStreamResult generateMD5Result(InputStream toEncode) { |
112 |
MD5Digest eTag = new MD5Digest();
|
113 |
byte[] resBuf = new byte[eTag.getDigestSize()]; |
114 |
byte[] buffer = new byte[1024]; |
115 |
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
116 |
long length = 0; |
117 |
int numRead = -1; |
118 |
try {
|
119 |
do {
|
120 |
numRead = toEncode.read(buffer); |
121 |
if (numRead > 0) { |
122 |
length += numRead; |
123 |
eTag.update(buffer, 0, numRead);
|
124 |
out.write(buffer, 0, numRead);
|
125 |
} |
126 |
} while (numRead != -1); |
127 |
} catch (IOException e) { |
128 |
throw new RuntimeException(e); |
129 |
} finally {
|
130 |
Closeables.closeQuietly(out); |
131 |
Closeables.closeQuietly(toEncode); |
132 |
} |
133 |
eTag.doFinal(resBuf, 0);
|
134 |
return new MD5InputStreamResult(out.toByteArray(), resBuf, length); |
135 |
} |
136 |
|
137 |
public byte[] fromBase64String(String encoded) { |
138 |
return Base64.decode(encoded);
|
139 |
} |
140 |
|
141 |
@Override
|
142 |
public MD5OutputStream md5OutputStream(OutputStream out) { |
143 |
return new BouncyCastleMD5OutputStream(out); |
144 |
} |
145 |
|
146 |
public static class BouncyCastleMD5OutputStream extends MD5OutputStream { |
147 |
public BouncyCastleMD5OutputStream(OutputStream out) { |
148 |
super(new DigestOutputStream(out, new MD5Digest())); |
149 |
} |
150 |
|
151 |
@Override
|
152 |
public byte[] getMD5() { |
153 |
MD5Digest digest = (MD5Digest) ((DigestOutputStream) out).getDigest();
|
154 |
byte[] resBuf = new byte[digest.getDigestSize()]; |
155 |
digest.doFinal(resBuf, 0);
|
156 |
return resBuf;
|
157 |
} |
158 |
} |
159 |
} |