Skip to content

Commit ea157d1

Browse files
authored
Merge pull request #346 from FlowCI/feature/1426
Feature/1426
2 parents 80cf84a + a97bb8a commit ea157d1

File tree

6 files changed

+63
-24
lines changed

6 files changed

+63
-24
lines changed

core/src/main/java/com/flowci/core/common/helper/CipherHelper.java

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,21 @@
2323
import com.jcraft.jsch.JSch;
2424
import com.jcraft.jsch.JSchException;
2525
import com.jcraft.jsch.KeyPair;
26+
import sun.security.util.DerInputStream;
27+
import sun.security.util.DerValue;
28+
29+
import javax.crypto.Cipher;
30+
import javax.crypto.spec.SecretKeySpec;
2631
import java.io.ByteArrayOutputStream;
2732
import java.io.IOException;
2833
import java.math.BigInteger;
2934
import java.nio.ByteBuffer;
3035
import java.nio.charset.StandardCharsets;
31-
import java.security.KeyFactory;
32-
import java.security.NoSuchAlgorithmException;
33-
import java.security.PrivateKey;
34-
import java.security.PublicKey;
36+
import java.security.*;
3537
import java.security.spec.InvalidKeySpecException;
3638
import java.security.spec.RSAPrivateCrtKeySpec;
3739
import java.security.spec.RSAPublicKeySpec;
3840
import java.util.Base64;
39-
import javax.crypto.Cipher;
40-
import javax.crypto.spec.SecretKeySpec;
41-
import sun.security.util.DerInputStream;
42-
import sun.security.util.DerValue;
4341

4442
public abstract class CipherHelper {
4543

@@ -100,8 +98,29 @@ public static String decrypt(String encrypted, String privateKey) {
10098
}
10199
}
102100

101+
public static String fingerprintMd5(String publicKey) throws NoSuchAlgorithmException {
102+
String derFormat = publicKey.split(" ")[1].trim();
103+
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
104+
byte[] digest = messageDigest.digest(Base64.getDecoder().decode(derFormat));
105+
final StringBuilder toRet = new StringBuilder();
106+
for (int i = 0; i < digest.length; i++) {
107+
if (i != 0) {
108+
toRet.append(":");
109+
}
110+
111+
int b = digest[i] & 0xff;
112+
String hex = Integer.toHexString(b);
113+
114+
if (hex.length() == 1) {
115+
toRet.append("0");
116+
}
117+
toRet.append(hex);
118+
}
119+
return toRet.toString();
120+
}
121+
103122
private static PrivateKey toPrivateKey(String key)
104-
throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
123+
throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
105124
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
106125

107126
String content = key.replaceAll("\\n", "").replace(RsaPrivateKeyStart, "").replace(RsaPrivateKeyEnd, "");
@@ -121,7 +140,7 @@ private static PrivateKey toPrivateKey(String key)
121140
BigInteger crtCoef = seq[8].getBigInteger();
122141

123142
RSAPrivateCrtKeySpec keySpec =
124-
new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
143+
new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
125144

126145
return keyFactory.generatePrivate(keySpec);
127146
}
@@ -130,7 +149,7 @@ private static PrivateKey toPrivateKey(String key)
130149
* from <type><space><base64data><space><comment> to public key
131150
*/
132151
private static PublicKey toPublicKey(String sshPublicKey)
133-
throws NoSuchAlgorithmException, InvalidKeySpecException {
152+
throws NoSuchAlgorithmException, InvalidKeySpecException {
134153
String[] line = sshPublicKey.trim().split(" ", 3);
135154
String type = line[0];
136155
String content = line[1];

core/src/main/java/com/flowci/core/secret/domain/RSASecret.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public final class RSASecret extends Secret {
3333

3434
private SimpleKeyPair pair;
3535

36+
private String md5Fingerprint;
37+
3638
public RSASecret() {
3739
this.pair = new SimpleKeyPair();
3840
this.setCategory(Category.SSH_RSA);

core/src/main/java/com/flowci/core/secret/service/SecretServiceImpl.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@
3131
import com.flowci.domain.SimpleKeyPair;
3232
import com.flowci.exception.DuplicateException;
3333
import com.flowci.exception.NotFoundException;
34+
import com.flowci.exception.StatusException;
3435
import com.flowci.util.StringHelper;
3536
import lombok.extern.log4j.Log4j2;
3637
import org.springframework.beans.factory.annotation.Autowired;
3738
import org.springframework.context.event.EventListener;
3839
import org.springframework.dao.DuplicateKeyException;
3940
import org.springframework.stereotype.Service;
4041

42+
import java.security.NoSuchAlgorithmException;
4143
import java.util.List;
4244
import java.util.Optional;
4345

@@ -94,20 +96,20 @@ public SimpleKeyPair genRSA() {
9496
public RSASecret createRSA(String name) {
9597
String email = sessionManager.get().getEmail();
9698
SimpleKeyPair pair = CipherHelper.RSA.gen(email);
97-
98-
RSASecret rsaCredential = new RSASecret();
99-
rsaCredential.setName(name);
100-
rsaCredential.setPair(pair);
101-
102-
return save(rsaCredential);
99+
return createRSA(name, pair);
103100
}
104101

105102
@Override
106103
public RSASecret createRSA(String name, SimpleKeyPair pair) {
107-
RSASecret rsaCredential = new RSASecret();
108-
rsaCredential.setName(name);
109-
rsaCredential.setPair(pair);
110-
return save(rsaCredential);
104+
try {
105+
RSASecret secret = new RSASecret();
106+
secret.setName(name);
107+
secret.setPair(pair);
108+
secret.setMd5Fingerprint(CipherHelper.RSA.fingerprintMd5(pair.getPublicKey()));
109+
return save(secret);
110+
} catch (NoSuchAlgorithmException e) {
111+
throw new StatusException("failed to generate fingerprint");
112+
}
111113
}
112114

113115
@Override

core/src/test/java/com/flowci/core/test/common/CipherHelperTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,17 @@
2020
import com.flowci.core.common.helper.CipherHelper;
2121
import com.flowci.core.common.helper.CipherHelper.RSA;
2222
import com.flowci.domain.SimpleKeyPair;
23+
import com.flowci.util.StringHelper;
2324
import com.google.common.base.Strings;
2425
import org.junit.Assert;
2526
import org.junit.Test;
2627

28+
import java.io.IOException;
29+
import java.io.InputStream;
30+
import java.security.NoSuchAlgorithmException;
31+
32+
import static com.flowci.core.common.helper.CipherHelper.RSA.fingerprintMd5;
33+
2734
public class CipherHelperTest {
2835

2936
private final String source = "!@#!@#!@1fsd";
@@ -53,4 +60,11 @@ public void should_encrypt_decrypt_by_rsa() {
5360

5461
Assert.assertEquals(source, decrypted);
5562
}
63+
64+
@Test
65+
public void should_create_public_key_fingerprint() throws IOException, NoSuchAlgorithmException {
66+
InputStream in = CipherHelper.class.getClassLoader().getResourceAsStream("pk_fingerprint");
67+
String publicKey = StringHelper.toString(in);
68+
Assert.assertEquals("09:e6:ce:d3:ba:a3:ee:75:9e:96:7b:55:12:85:c6:4e", fingerprintMd5(publicKey));
69+
}
5670
}

core/src/test/java/com/flowci/core/test/secret/SecretServiceTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ public void should_create_rsa_secret() {
5757
Secret loaded = secretService.get("hello.rsa");
5858
Assert.assertTrue(loaded instanceof RSASecret);
5959

60-
RSASecret keyPair = (RSASecret) loaded;
61-
Assert.assertFalse(Strings.isNullOrEmpty(keyPair.getPublicKey()));
62-
Assert.assertFalse(Strings.isNullOrEmpty(keyPair.getPrivateKey()));
60+
RSASecret secret = (RSASecret) loaded;
61+
Assert.assertFalse(Strings.isNullOrEmpty(secret.getPublicKey()));
62+
Assert.assertFalse(Strings.isNullOrEmpty(secret.getPrivateKey()));
63+
Assert.assertNotNull(secret.getMd5Fingerprint());
6364
}
6465

6566
@Test
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl7ATm/Rsk5jj8oQA3wxxqJFyeYHkcRHxzt+cNnfquwRugnnB0Hh8JBMACeG+es/14jI9tErh4oKGzTiEcCTnBe05C3MVNTbvtO6lP6rM4E+bSJwip2jNKYP7Ozofim2xgD55tGDdWQtBdDOiQWGQAvx+JDLPLGlWYoi1CBnC2zzVHtJCq9+eVhHvghDIjuO1+9iJUwkmh+38ABK2wMxugx46qaNHJuF1p/ncQCB9vb5c6mq3lZQH1usujMGWOH0jctoJVzXX8cJapROWPKombl0svO8+GKAG4FuLcrx+W7OSKCweKPgpnCloCp5Up/zzZeheG8gIYpQPiIvEEKLTb [email protected]

0 commit comments

Comments
 (0)