Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
reg-app
Regapp
Commits
35daa9d1
Commit
35daa9d1
authored
Jan 15, 2019
by
michael.simon
Browse files
add open ssh key decoder
parent
8c9a3f06
Changes
2
Hide whitespace changes
Inline
Side-by-side
bwreg-service/src/main/java/edu/kit/scc/webreg/ssh/OpenSshKeyDecoder.java
0 → 100644
View file @
35daa9d1
package
edu.kit.scc.webreg.ssh
;
import
java.io.Serializable
;
import
java.math.BigInteger
;
import
java.security.AlgorithmParameters
;
import
java.security.KeyFactory
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.spec.DSAPublicKeySpec
;
import
java.security.spec.ECGenParameterSpec
;
import
java.security.spec.ECParameterSpec
;
import
java.security.spec.ECPoint
;
import
java.security.spec.ECPublicKeySpec
;
import
java.security.spec.InvalidKeySpecException
;
import
java.security.spec.InvalidParameterSpecException
;
import
java.security.spec.RSAPublicKeySpec
;
import
javax.enterprise.context.ApplicationScoped
;
import
org.apache.commons.codec.binary.Base64
;
import
org.bouncycastle.jce.ECNamedCurveTable
;
import
org.bouncycastle.jce.spec.ECNamedCurveParameterSpec
;
@ApplicationScoped
public
class
OpenSshKeyDecoder
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
public
OpenSshPublicKey
decode
(
String
opensshPublicKey
)
{
OpenSshPublicKey
key
=
new
OpenSshPublicKey
();
key
.
setBytes
(
getKeyBytes
(
opensshPublicKey
));
try
{
String
type
=
decodeType
(
key
);
if
(
type
.
equals
(
"ssh-rsa"
))
{
BigInteger
e
=
decodeBigInt
(
key
);
BigInteger
m
=
decodeBigInt
(
key
);
RSAPublicKeySpec
spec
=
new
RSAPublicKeySpec
(
m
,
e
);
key
.
setPublicKey
(
KeyFactory
.
getInstance
(
"RSA"
).
generatePublic
(
spec
));
}
else
if
(
type
.
equals
(
"ssh-dss"
))
{
BigInteger
p
=
decodeBigInt
(
key
);
BigInteger
q
=
decodeBigInt
(
key
);
BigInteger
g
=
decodeBigInt
(
key
);
BigInteger
y
=
decodeBigInt
(
key
);
DSAPublicKeySpec
spec
=
new
DSAPublicKeySpec
(
y
,
p
,
q
,
g
);
key
.
setPublicKey
(
KeyFactory
.
getInstance
(
"DSA"
).
generatePublic
(
spec
));
}
else
if
(
type
.
startsWith
(
"ecdsa-sha2-"
)
&&
(
type
.
endsWith
(
"nistp256"
)
||
type
.
endsWith
(
"nistp384"
)
||
type
.
endsWith
(
"nistp521"
)))
{
// Based on RFC 5656, section 3.1 (https://tools.ietf.org/html/rfc5656#section-3.1)
String
identifier
=
decodeType
(
key
);
BigInteger
q
=
decodeBigInt
(
key
);
ECPoint
ecPoint
=
getECPoint
(
q
,
identifier
);
ECParameterSpec
ecParameterSpec
=
getECParameterSpec
(
identifier
);
ECPublicKeySpec
spec
=
new
ECPublicKeySpec
(
ecPoint
,
ecParameterSpec
);
key
.
setPublicKey
(
KeyFactory
.
getInstance
(
"EC"
).
generatePublic
(
spec
));
}
else
{
throw
new
IllegalArgumentException
(
"Unsupported key type "
+
type
);
}
return
key
;
}
catch
(
NoSuchAlgorithmException
|
InvalidKeySpecException
e
)
{
throw
new
IllegalArgumentException
(
"Unable to decode public key"
,
e
);
}
}
private
byte
[]
getKeyBytes
(
String
opensshPublicKey
)
{
for
(
String
part
:
opensshPublicKey
.
split
(
" "
))
{
if
(
Base64
.
isBase64
(
part
)
&&
part
.
startsWith
(
"AAAA"
))
{
return
Base64
.
decodeBase64
(
part
);
}
}
throw
new
IllegalArgumentException
(
"no Base64 part to decode"
);
}
private
String
decodeType
(
OpenSshPublicKey
key
)
{
int
len
=
decodeInt
(
key
);
String
type
=
new
String
(
key
.
getBytes
(),
key
.
getDecoderPos
(),
len
);
key
.
increaseDecoderPos
(
len
);
return
type
;
}
private
int
decodeInt
(
OpenSshPublicKey
key
)
{
byte
[]
bytes
=
key
.
getBytes
();
int
pos
=
key
.
getDecoderPos
();
int
header
=
((
bytes
[
pos
]
&
0xFF
)
<<
24
)
|
((
bytes
[
pos
]
&
0xFF
)
<<
16
)
|
((
bytes
[
pos
]
&
0xFF
)
<<
8
)
|
(
bytes
[
pos
]
&
0xFF
);
key
.
increaseDecoderPos
(
4
);
return
header
;
}
private
BigInteger
decodeBigInt
(
OpenSshPublicKey
key
)
{
int
len
=
decodeInt
(
key
);
byte
[]
bigIntBytes
=
new
byte
[
len
];
System
.
arraycopy
(
key
.
getBytes
(),
key
.
getDecoderPos
(),
bigIntBytes
,
0
,
len
);
key
.
increaseDecoderPos
(
len
);
return
new
BigInteger
(
bigIntBytes
);
}
ECPoint
getECPoint
(
BigInteger
q
,
String
identifier
)
{
String
name
=
identifier
.
replace
(
"nist"
,
"sec"
)
+
"r1"
;
ECNamedCurveParameterSpec
ecSpec
=
ECNamedCurveTable
.
getParameterSpec
(
name
);
org
.
bouncycastle
.
math
.
ec
.
ECPoint
point
=
ecSpec
.
getCurve
().
decodePoint
(
q
.
toByteArray
());
BigInteger
x
=
point
.
getAffineXCoord
().
toBigInteger
();
BigInteger
y
=
point
.
getAffineYCoord
().
toBigInteger
();
return
new
ECPoint
(
x
,
y
);
}
ECParameterSpec
getECParameterSpec
(
String
identifier
)
{
try
{
// http://www.bouncycastle.org/wiki/pages/viewpage.action?pageId=362269#SupportedCurves(ECDSAandECGOST)-NIST(aliasesforSECcurves)
String
name
=
identifier
.
replace
(
"nist"
,
"sec"
)
+
"r1"
;
AlgorithmParameters
parameters
=
AlgorithmParameters
.
getInstance
(
"EC"
);
parameters
.
init
(
new
ECGenParameterSpec
(
name
));
return
parameters
.
getParameterSpec
(
ECParameterSpec
.
class
);
}
catch
(
InvalidParameterSpecException
|
NoSuchAlgorithmException
e
)
{
throw
new
IllegalArgumentException
(
"Unable to get parameter spec for identifier "
+
identifier
,
e
);
}
}
}
bwreg-service/src/main/java/edu/kit/scc/webreg/ssh/OpenSshPublicKey.java
0 → 100644
View file @
35daa9d1
package
edu.kit.scc.webreg.ssh
;
import
java.security.PublicKey
;
public
class
OpenSshPublicKey
{
private
byte
[]
bytes
;
private
int
decoderPos
;
private
PublicKey
publicKey
;
public
OpenSshPublicKey
()
{
super
();
decoderPos
=
0
;
}
public
byte
[]
getBytes
()
{
return
bytes
;
}
public
void
setBytes
(
byte
[]
bytes
)
{
this
.
bytes
=
bytes
;
}
public
int
getDecoderPos
()
{
return
decoderPos
;
}
public
void
setDecoderPos
(
int
decoderPos
)
{
this
.
decoderPos
=
decoderPos
;
}
public
void
increaseDecoderPos
(
int
steps
)
{
this
.
decoderPos
+=
steps
;
}
public
PublicKey
getPublicKey
()
{
return
publicKey
;
}
public
void
setPublicKey
(
PublicKey
publicKey
)
{
this
.
publicKey
=
publicKey
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment