Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
IDPServer
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Josh Ji
IDPServer
Commits
7cfca8a9
Commit
7cfca8a9
authored
Jan 22, 2024
by
Josh Ji
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ask id v2, docker compose, hkdf, hmac
parent
542a0033
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
331 additions
and
13 deletions
+331
-13
Dockerfile
Dockerfile
+6
-5
docker-compose.yml
docker-compose.yml
+29
-0
src/main/java/com/prlab/idpserver/controller/askIdentity.java
...main/java/com/prlab/idpserver/controller/askIdentity.java
+2
-5
src/main/java/com/prlab/idpserver/controller/askIdentityV2.java
...in/java/com/prlab/idpserver/controller/askIdentityV2.java
+129
-0
src/main/java/com/prlab/idpserver/hkdf/HKDF.java
src/main/java/com/prlab/idpserver/hkdf/HKDF.java
+75
-0
src/main/java/com/prlab/idpserver/hkdf/HMAC.java
src/main/java/com/prlab/idpserver/hkdf/HMAC.java
+79
-0
src/main/java/com/prlab/idpserver/model/IdentityRequestV2.java
...ain/java/com/prlab/idpserver/model/IdentityRequestV2.java
+8
-0
testDB.sql
testDB.sql
+3
-3
No files found.
Dockerfile
View file @
7cfca8a9
FROM
maven AS build
COPY
. /tmp
WORKDIR
/tmp
RUN
mvn clean package
-DskipTests
#
FROM maven AS build
#
COPY . /tmp
#
WORKDIR /tmp
#
RUN mvn clean package -DskipTests
FROM
openjdk:11-jre-slim
COPY
--from=build /tmp/target/*.jar app.jar
#COPY --from=build /tmp/target/*.jar app.jar
COPY
target/*.jar app.jar
EXPOSE
8086
ENV
SPRING_DATASOURCE_USERNAME=root
ENV
SPRING_DATASOURCE_PASSWORD=rootpasswd
...
...
docker-compose.yml
0 → 100644
View file @
7cfca8a9
services
:
mysql
:
image
:
mysql:8
environment
:
MYSQL_ROOT_PASSWORD
:
root
MYSQL_DATABASE
:
idp
MYSQL_USER
:
idp
MYSQL_PASSWORD
:
idppasswd
volumes
:
-
"
./Dump20231106.sql:/docker-entrypoint-initdb.d/1.sql"
ports
:
-
32306:3306
rpserver
:
image
:
rpserver
environment
:
IDP_URL
:
http://idpserver:8086/
ports
:
-
443:443
idpserver
:
image
:
idpserver
environment
:
SPRING_DATASOURCE_USERNAME
:
idp
SPRING_DATASOURCE_PASSWORD
:
idppasswd
SPRING_DATASOURCE_URL
:
jdbc:mysql://mysql/idp
ports
:
-
8086:8086
networks
:
overlay
:
driver
:
overlay
\ No newline at end of file
src/main/java/com/prlab/idpserver/controller/
RESTfulApi
.java
→
src/main/java/com/prlab/idpserver/controller/
askIdentity
.java
View file @
7cfca8a9
...
...
@@ -12,9 +12,6 @@ import org.springframework.web.bind.annotation.*;
import
javax.crypto.*
;
import
javax.crypto.spec.IvParameterSpec
;
import
javax.crypto.spec.SecretKeySpec
;
import
java.security.InvalidAlgorithmParameterException
;
import
java.security.InvalidKeyException
;
import
java.security.NoSuchAlgorithmException
;
import
java.sql.Types
;
import
java.util.Arrays
;
import
java.util.List
;
...
...
@@ -22,11 +19,11 @@ import java.util.Map;
@RestController
@RequestMapping
(
"/api"
)
public
class
RESTfulApi
{
public
class
askIdentity
{
@Autowired
JdbcTemplate
jdbcTemplate
=
new
JdbcTemplate
();
Logger
logger
=
LoggerFactory
.
getLogger
(
RESTfulApi
.
class
);
Logger
logger
=
LoggerFactory
.
getLogger
(
askIdentity
.
class
);
@PostMapping
(
"/idp/askIdentity"
)
...
...
src/main/java/com/prlab/idpserver/controller/askIdentityV2.java
0 → 100644
View file @
7cfca8a9
package
com.prlab.idpserver.controller
;
import
com.prlab.idpserver.hkdf.HKDF
;
import
com.prlab.idpserver.model.IdentityRequestV2
;
import
org.apache.tomcat.util.buf.HexUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.jdbc.core.JdbcTemplate
;
import
org.springframework.util.Base64Utils
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.crypto.Mac
;
import
javax.crypto.spec.SecretKeySpec
;
import
java.math.BigInteger
;
import
java.nio.ByteBuffer
;
import
java.nio.charset.StandardCharsets
;
import
java.security.InvalidKeyException
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
import
java.sql.Types
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.atomic.AtomicReference
;
@RestController
@RequestMapping
(
"/api"
)
public
class
askIdentityV2
{
@Autowired
JdbcTemplate
jdbcTemplate
=
new
JdbcTemplate
();
Logger
logger
=
LoggerFactory
.
getLogger
(
askIdentityV2
.
class
);
@PostMapping
(
"/idp/askIdentityV2"
)
public
String
queryIdentity
(
@RequestBody
IdentityRequestV2
r
){
logger
.
info
(
"r : {}, {}, {}, {}"
,
r
.
nonce_base64
,
r
.
idHash_base64
,
r
.
cE_base64
,
r
.
HMAC_base64
);
byte
[]
nonce
=
Base64Utils
.
decodeFromString
(
r
.
nonce_base64
);
byte
[]
idHash
=
Base64Utils
.
decodeFromString
(
r
.
idHash_base64
);
byte
[]
cE
=
Base64Utils
.
decodeFromString
(
r
.
cE_base64
);
byte
[]
hmac
=
Base64Utils
.
decodeFromString
(
r
.
HMAC_base64
);
logger
.
info
(
"nonce: {}\nidHash: {}\ncE: {}\nhmac: {}\n"
,
HexUtils
.
toHexString
(
nonce
),
HexUtils
.
toHexString
(
idHash
),
HexUtils
.
toHexString
(
cE
),
HexUtils
.
toHexString
(
hmac
)
);
String
sql_query_by_id_hash
=
"select * from pivinfo "
+
"where hex(?)=sha2(unhex(concat(sha2(id, 256), sha2(?, 256))), 256) limit 1;"
;
// String sql_query_by_id_hash = "SELECT * FROM users " +
// "WHERE hex(?)=sha2(unhex(concat(sha2(uid, 256), sha2(?, 256))), 256)";
long
t1
=
System
.
currentTimeMillis
();
List
<
Map
<
String
,
Object
>>
list
=
jdbcTemplate
.
queryForList
(
sql_query_by_id_hash
,
new
Object
[]{
Base64Utils
.
decodeFromString
(
r
.
idHash_base64
),
Base64Utils
.
decodeFromString
(
r
.
nonce_base64
)},
new
int
[]{
Types
.
VARBINARY
,
Types
.
VARBINARY
});
long
t2
=
System
.
currentTimeMillis
();
logger
.
info
(
"time consumed: {} ms"
,
t2
-
t1
);
BigInteger
nonceInt
=
new
BigInteger
(
nonce
);
BigInteger
nonceInt1
=
nonceInt
.
add
(
new
BigInteger
(
String
.
valueOf
(
1
)));
AtomicReference
<
String
>
msg
=
new
AtomicReference
<>(
"Your Identity is Invalid.,"
+
(
t2
-
t1
));
list
.
forEach
(
map
->{
String
id
=
(
String
)
map
.
get
(
"id"
);
try
{
MessageDigest
sha256
=
MessageDigest
.
getInstance
(
"SHA-256"
);
byte
[]
idSha256
=
sha256
.
digest
(
id
.
getBytes
(
StandardCharsets
.
UTF_8
));
byte
[]
nonce1Sha256
=
sha256
.
digest
(
nonceInt1
.
toByteArray
());
sha256
.
update
(
idSha256
);
byte
[]
idHash1
=
sha256
.
digest
(
nonce1Sha256
);
byte
[]
counter
=
new
byte
[
cE
.
length
];
xor
(
cE
,
idHash1
,
counter
);
ByteBuffer
byteBuffer
=
ByteBuffer
.
allocate
(
Long
.
BYTES
);
// uint32 to int64(long)
byteBuffer
.
put
(
new
byte
[
4
]);
byteBuffer
.
put
(
counter
);
byteBuffer
.
rewind
();
long
c
=
byteBuffer
.
getLong
();
logger
.
info
(
"id: {}"
,
id
);
logger
.
info
(
"c: {}"
,
c
);
HKDF
hkdf
=
new
HKDF
((
byte
[])
map
.
get
(
"sharedSecret"
),
(
byte
[])
map
.
get
(
"hkdf_chain_iv"
),
c
);
long
t3
=
System
.
nanoTime
();
byte
[]
outputKey
=
hkdf
.
getOutputKey
(((
String
)
map
.
get
(
"id"
)).
getBytes
(
StandardCharsets
.
UTF_8
),
32
);
long
t4
=
System
.
nanoTime
();
logger
.
info
(
"t4-t3: {}"
,
t4
-
t3
);
Mac
h256
=
Mac
.
getInstance
(
"HmacSHA256"
);
h256
.
init
(
new
SecretKeySpec
(
outputKey
,
"HmacSHA256"
));
byte
[]
hmac_
=
h256
.
doFinal
(
idHash
);
print
(
"hmac_"
,
hmac_
);
print
(
"hmac"
,
hmac
);
if
(
Arrays
.
equals
(
hmac
,
hmac_
)){
logger
.
info
(
"hmac is correct"
);
msg
.
set
(
"Your Identity is Valid.,"
+
(
t2
-
t1
));
}
}
catch
(
NoSuchAlgorithmException
|
InvalidKeyException
e
)
{
throw
new
RuntimeException
(
e
);
}
});
if
(
list
.
size
()>
0
)
// return (String)list.get(0).get("id");
return
msg
.
get
();
else
return
"IDENTITY_NOT_FOUND"
;
}
public
void
xor
(
byte
[]
a
,
byte
[]
b
,
byte
[]
output
){
for
(
short
i
=
0
;
i
<
a
.
length
;
i
++){
output
[
i
]
=
(
byte
)(
a
[
i
]
^
b
[
i
]);
}
}
public
void
print
(
byte
[]
data
){
logger
.
info
(
HexUtils
.
toHexString
(
data
));
}
public
void
print
(
String
tag
,
byte
[]
data
){
logger
.
info
(
"{}: {}"
,
tag
,
HexUtils
.
toHexString
(
data
));
}
}
src/main/java/com/prlab/idpserver/hkdf/HKDF.java
0 → 100644
View file @
7cfca8a9
package
com.prlab.idpserver.hkdf
;
import
javax.crypto.SecretKey
;
import
java.nio.ByteBuffer
;
import
java.security.NoSuchAlgorithmException
;
public
class
HKDF
{
private
final
byte
[]
key
;
private
final
byte
[]
iv
;
private
long
iterate
;
private
HMAC
hmac
;
public
HKDF
(
byte
[]
key
,
byte
[]
iv
,
long
iterate
)
throws
NoSuchAlgorithmException
{
this
.
key
=
key
;
this
.
iv
=
iv
;
this
.
iterate
=
iterate
;
this
.
hmac
=
new
HMAC
(
key
);
}
private
byte
[]
extract
(
byte
[]
salt
,
byte
[]
ikm
)
throws
NoSuchAlgorithmException
{
hmac
.
setKey
(
salt
);
hmac
.
update
(
ikm
);
return
hmac
.
doFinal
();
}
private
byte
[]
expand
(
byte
[]
prk
,
byte
[]
info
,
int
outLengthBytes
)
throws
NoSuchAlgorithmException
{
// sha256 maclength is always 32
int
n
=
(
int
)
Math
.
ceil
(((
double
)
outLengthBytes
)
/
((
double
)
32
));
if
(
n
>
255
)
{
throw
new
IllegalArgumentException
(
"out length must be maximal 255 * hash-length; requested: "
+
outLengthBytes
+
" bytes"
);
}
byte
[]
blockN
;
byte
[]
ret
=
new
byte
[
outLengthBytes
];
int
stepSize
=
0
;
int
remainingBytes
=
outLengthBytes
;
for
(
int
i
=
0
;
i
<
n
;
i
++
){
hmac
.
setKey
(
prk
);
hmac
.
update
(
info
);
byte
[]
counter
=
{(
byte
)(
i
+
1
)};
hmac
.
update
(
counter
);
blockN
=
hmac
.
doFinal
();
stepSize
=
blockN
.
length
;
if
(
stepSize
<
remainingBytes
){
arrayCopy
(
ret
,
blockN
,
outLengthBytes
-
remainingBytes
,
stepSize
);
remainingBytes
-=
stepSize
;
}
else
{
arrayCopy
(
ret
,
blockN
,
outLengthBytes
-
remainingBytes
,
remainingBytes
);
}
}
return
ret
;
}
public
byte
[]
getPRK
()
throws
NoSuchAlgorithmException
{
byte
[]
prf
=
this
.
iv
;
for
(
long
i
=
0
;
i
<
this
.
iterate
;
i
++
){
prf
=
extract
(
prf
,
this
.
key
);
}
return
prf
;
}
public
byte
[]
getOutputKey
(
byte
[]
info
,
int
outLengthBytes
)
throws
NoSuchAlgorithmException
{
byte
[]
outputKey
;
byte
[]
salt
=
this
.
iv
;
for
(
long
i
=
0
;
i
<
this
.
iterate
;
i
++){
salt
=
extract
(
salt
,
this
.
key
);
}
outputKey
=
expand
(
salt
,
info
,
outLengthBytes
);
return
outputKey
;
}
private
static
void
arrayCopy
(
byte
[]
arr1
,
byte
[]
arr2
,
int
start
,
int
offset
){
for
(
int
i
=
0
;
i
<
offset
;
i
++
){
arr1
[
start
+
i
]
=
arr2
[
i
];
}
}
}
src/main/java/com/prlab/idpserver/hkdf/HMAC.java
0 → 100644
View file @
7cfca8a9
package
com.prlab.idpserver.hkdf
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
public
class
HMAC
{
private
byte
[]
key
;
private
byte
[]
msg
;
private
byte
[]
opad
=
new
byte
[
64
];
private
byte
[]
ipad
=
new
byte
[
64
];
public
HMAC
(
byte
[]
key
)
throws
NoSuchAlgorithmException
{
setKey
(
key
);
for
(
int
i
=
0
;
i
<
opad
.
length
;
++
i
)
{
opad
[
i
]
=
0x5c
;
ipad
[
i
]
=
0x36
;
}
}
public
void
setKey
(
byte
[]
key
)
throws
NoSuchAlgorithmException
{
if
(
key
==
null
){
return
;
}
else
if
(
key
.
length
<
64
){
this
.
key
=
padding
(
key
,
64
);
}
else
{
this
.
key
=
hash
(
key
);
}
}
public
void
update
(
byte
[]
m
){
if
(
this
.
msg
==
null
){
this
.
msg
=
m
;
}
else
{
this
.
msg
=
concat
(
this
.
msg
,
m
);
}
}
// force use SHA256
public
byte
[]
doFinal
()
throws
NoSuchAlgorithmException
{
byte
[]
output
=
hash
(
concat
(
xor
(
this
.
key
,
opad
),
hash
((
concat
(
xor
(
this
.
key
,
ipad
),
this
.
msg
)))));
this
.
msg
=
null
;
return
output
;
}
private
byte
[]
padding
(
byte
[]
key
,
int
length
){
byte
[]
ret
=
new
byte
[
length
];
for
(
int
i
=
0
;
i
<
length
;
i
++){
if
(
i
>=
key
.
length
){
ret
[
i
]
=
0
;
}
else
{
ret
[
i
]
=
key
[
i
];
}
}
return
ret
;
}
public
static
byte
[]
xor
(
byte
[]
a
,
byte
[]
b
)
{
byte
[]
result
=
new
byte
[
Math
.
max
(
a
.
length
,
b
.
length
)];
for
(
int
i
=
0
;
i
<
result
.
length
;
++
i
)
{
result
[
i
]
=
(
byte
)
(
0xff
&
((
int
)
a
[
i
]
^
(
int
)
b
[
i
]));
}
return
result
;
}
public
static
byte
[]
concat
(
byte
[]
a
,
byte
[]
b
){
byte
[]
ret
=
new
byte
[
a
.
length
+
b
.
length
];
for
(
int
i
=
0
;
i
<
a
.
length
;
i
++){
ret
[
i
]
=
a
[
i
];
}
for
(
int
i
=
0
;
i
<
b
.
length
;
i
++){
ret
[
i
+
a
.
length
]
=
b
[
i
];
}
return
ret
;
}
private
byte
[]
hash
(
byte
[]
m
)
throws
NoSuchAlgorithmException
{
MessageDigest
md
=
MessageDigest
.
getInstance
(
"SHA-256"
);
return
md
.
digest
(
m
);
}
}
src/main/java/com/prlab/idpserver/model/IdentityRequestV2.java
0 → 100644
View file @
7cfca8a9
package
com.prlab.idpserver.model
;
public
class
IdentityRequestV2
{
public
String
nonce_base64
;
public
String
idHash_base64
;
public
String
cE_base64
;
public
String
HMAC_base64
;
}
testDB.sql
View file @
7cfca8a9
...
...
@@ -27,8 +27,8 @@ DROP TABLE IF EXISTS `identities`;
CREATE
TABLE
`identities`
(
`SerialNumber`
int
NOT
NULL
AUTO_INCREMENT
,
`IDx`
varchar
(
64
)
COLLATE
utf8_bin
NOT
NULL
,
`HMAC`
varbinary
(
32
)
NOT
NULL
,
`HMACbase64`
varchar
(
45
)
COLLATE
utf8_bin
DEFAULT
'None'
,
`HMAC`
varbinary
(
64
)
NOT
NULL
,
`HMACbase64`
varchar
(
100
)
COLLATE
utf8_bin
DEFAULT
'None'
,
`Cx`
varbinary
(
16
)
NOT
NULL
,
`SharedSecret`
varbinary
(
32
)
NOT
NULL
,
`PuKx`
varbinary
(
128
)
NOT
NULL
,
...
...
@@ -45,7 +45,7 @@ CREATE TABLE `identities` (
LOCK
TABLES
`identities`
WRITE
;
/*!40000 ALTER TABLE `identities` DISABLE KEYS */
;
INSERT
INTO
`identities`
VALUES
(
29
,
'prlab'
,
_binary
'
\Y
m? Ci.XX
\4
|trؖ+
\'
,'
vbeOm85Z8W0
/
IENpDi5YWOs0sr60fKV0hHL92JYrkds
=
',_binary '
+
;
К
v
\
(
\\
',_binary '
w
\
R
m
\
FaC
\\
v
/
\\
FS
knC
',_binary '
ECK1
\
0
\
0
\
02
+/
\\\\
6
\
6
\\
LUc
~|
y
\\
A
\\
_e
\
(
D
g
\
Q
\
&
\
B5j
-
Ӭ\\\
^
B
',_binary '
ECK1
\
0
\
0
\
0
g
{\
'Ӗ
\
>z
\\8\\
AD@W
\\
t >f
\r
N^K
\?
:3;9X
\!
f'
,
_binary
'0w
\5
/}H
\\
rH_CtInr{V
\r\\
o
\n
*H
\=
DB
\0
g{
\'
Ӗ
\
>z
\\8\\
AD@W
\\
t >f
\r
N^K
\?
:3;9X
\
!
f'
);
INSERT
INTO
`identities`
VALUES
(
29
,
'prlab'
,
_binary
'
����
\�
Y�m? Ci.XX
\�
4���|�t�r�ؖ+�
\�
'
,
'vbeOm85Z8W0/IENpDi5YWOs0sr60fKV0hHL92JYrkds='
,
_binary
'�+;��v
\�
(�
\�\�
'
,
_binary
'�w
\�
R�m
\�
Fa�C�
\�\�
v�/
\�
�
\�
FS�k��nC'
,
_binary
'ECK1
\0\0\0
2�+/�
\�\�\�\�
6�
\�
�6�
\�\�
L�Uc~|���y
\�\�
A
\\
_e
\�
(Dg
\�
Q
\�
��&
\�
B5j�-Ӭ
\�\�\�
^�B'
,
_binary
'ECK1
\0\0\0
g{
\'
Ӗ
\�
>����z
\�
�
\�
8�
\�
�
\�
A�D@W
\�\�
t� �>f� �
\r
N^K
\�
?�:3;�9X
\�
!f'
,
_binary
'0w �
\�
5�/}H��
\�\r
����H_Ct��In�r{�V
\r\\
o�
\n
*�H
\�
=�DB
\0
g{
\'
Ӗ
\�
>����z
\�
�
\�
8�
\�
�
\�
A�D@W
\�\�
t� �>f� �
\r
N^K
\�
?�:3;�9X
\�
!f'
);
/*!40000 ALTER TABLE `identities` ENABLE KEYS */
;
UNLOCK
TABLES
;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */
;
...
...
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