Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qa-platform
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
QA
qa-platform
Commits
296382a3
Commit
296382a3
authored
Feb 24, 2021
by
黎博
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
更新
parent
98c50808
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1329 additions
and
4 deletions
+1329
-4
EncryptConvertor.java
.../qg/qaplatform/mock/encrypt/factory/EncryptConvertor.java
+8
-0
EncryptFactory.java
...cn/qg/qaplatform/mock/encrypt/factory/EncryptFactory.java
+18
-0
YeebaoEncryptConvertor.java
...platform/mock/encrypt/factory/YeebaoEncryptConvertor.java
+50
-0
AbstractConvertUtils.java
...platform/mock/encrypt/paycenter/AbstractConvertUtils.java
+23
-0
Aes.java
...ain/java/cn/qg/qaplatform/mock/encrypt/paycenter/Aes.java
+121
-0
Base64.java
.../java/cn/qg/qaplatform/mock/encrypt/paycenter/Base64.java
+590
-0
CheckUtils.java
...a/cn/qg/qaplatform/mock/encrypt/paycenter/CheckUtils.java
+33
-0
ConfigureEncryptAndDecrypt.java
...rm/mock/encrypt/paycenter/ConfigureEncryptAndDecrypt.java
+8
-0
Digest.java
.../java/cn/qg/qaplatform/mock/encrypt/paycenter/Digest.java
+164
-0
EncryUtil.java
...va/cn/qg/qaplatform/mock/encrypt/paycenter/EncryUtil.java
+80
-0
RandomUtil.java
...a/cn/qg/qaplatform/mock/encrypt/paycenter/RandomUtil.java
+22
-0
Rsa.java
...ain/java/cn/qg/qaplatform/mock/encrypt/paycenter/Rsa.java
+164
-0
PayInterceptor.java
...ava/cn/qg/qaplatform/mock/interceptor/PayInterceptor.java
+48
-4
No files found.
src/main/java/cn/qg/qaplatform/mock/encrypt/factory/EncryptConvertor.java
0 → 100644
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
factory
;
public
interface
EncryptConvertor
{
String
encrypt
(
String
response
);
String
decrypt
(
String
request
);
}
src/main/java/cn/qg/qaplatform/mock/encrypt/factory/EncryptFactory.java
0 → 100644
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
factory
;
import
lombok.extern.slf4j.Slf4j
;
@Slf4j
public
class
EncryptFactory
{
public
static
EncryptConvertor
produce
(
String
type
)
{
if
(
"yeebao"
.
equals
(
type
))
{
return
new
YeebaoEncryptConvertor
();
}
else
{
log
.
info
(
"请输入正确的加密类型类型!"
);
return
null
;
}
}
}
src/main/java/cn/qg/qaplatform/mock/encrypt/factory/YeebaoEncryptConvertor.java
0 → 100644
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
factory
;
import
cn.qg.qaplatform.mock.encrypt.paycenter.Aes
;
import
cn.qg.qaplatform.mock.encrypt.paycenter.Rsa
;
import
cn.qg.qaplatform.utils.JsonTransUtils
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
YeebaoEncryptConvertor
implements
EncryptConvertor
{
private
final
String
privateKey
=
"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANSBQSc0Hlr+mS7uoIjYS71X2DJ6ZrCcbB1uICqty9QY6W16nZ8tLN/d9k2Z+e2rGG8s7PskpU2T+WuJeDSXs/vpPllG8/tSRVaWcr9EzPaSti3ltSUH0QOLSypZEjTT/slscExj4PMOmQXUXP3gewjNWz1cYRI7dGnKPm+ZFah/AgMBAAECgYB8AcFngz6DkzcI8C+2K6JnJ6/+JPdv8JgWxID45tqfNrphLMB2dwJM0VY+CrCSRNnJZsoT9FqSXtuaKWqAJlbchhPZjupA9RkWFzlGpCQ63/CC71RYYY03eCnc7AIpn52whkjfWG/yf57jKzEwUT+U034uvXdaA+lVvJ0xqpj3gQJBAOmLODjecn450TJbNQaop+7Q5Hz2TUIxbYakzPpcLGv1QYgHa657r7PJ23ZltDBGldMaNTZfqJrtDcq0rTA4lBECQQDo8CcdUhMZ3JbR2UZN0CG8ljMbNWgNWBa37ebE3ZG5yYldc7zY9US/+/7lhxNDqG0saTvM9pJwEc3ccVMvksOPAkEAqq7V+zIQKVJmItBn06MFgNNoei+kTUFEk8f0CvG8gXYwW5NYzp+UzOg1HbW82B9uNmeMBl4pInknwEMF5B0lkQJAdRxQPgCGk+kAdo6LNxHd9Ed7eEF4h8Ty3xQfgnh3DHYTtsU6e8WMBA24kENB3zEtejeKFjkdVHTPD/Z1wSRDZwJAAvNuq0YuRDsESOAerkBZKonA5CD0M4vHTRqihHrjBohv6yxBU8P7gALrX7qmoaZ3aLmN8wHdOAGTR6LZjQdkoQ=="
;
private
String
aesKey
=
null
;
private
String
encryptKey
=
null
;
/**
* 易宝加密
* @param response
* @return
*/
@Override
public
String
encrypt
(
String
response
)
{
try
{
Map
responseMap
=
JsonTransUtils
.
strToMap
(
response
);
responseMap
.
put
(
"sign"
,
Rsa
.
sign
(
response
,
privateKey
));
responseMap
.
put
(
"data"
,
Aes
.
encryptToBase64
(
response
,
aesKey
));
return
JsonTransUtils
.
mapToJson
(
responseMap
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
/**
* 易宝解密
* @param request Http请求的request
* @return
*/
@Override
public
String
decrypt
(
String
request
)
{
try
{
Map
requestMap
=
JsonTransUtils
.
strToMap
(
request
);
aesKey
=
Rsa
.
decrypt
((
String
)
requestMap
.
get
(
"encryptkey"
),
privateKey
);
return
Aes
.
decryptFromBase64
((
String
)
requestMap
.
get
(
"data"
),
aesKey
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
}
src/main/java/cn/qg/qaplatform/mock/encrypt/paycenter/AbstractConvertUtils.java
0 → 100644
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
paycenter
;
public
abstract
class
AbstractConvertUtils
{
private
AbstractConvertUtils
()
{
}
public
static
String
toHex
(
byte
input
[])
{
if
(
input
==
null
)
{
return
null
;
}
StringBuffer
output
=
new
StringBuffer
(
input
.
length
*
2
);
for
(
int
i
=
0
;
i
<
input
.
length
;
i
++)
{
int
current
=
input
[
i
]
&
0xff
;
if
(
current
<
16
)
{
output
.
append
(
"0"
);
}
output
.
append
(
Integer
.
toString
(
current
,
16
));
}
return
output
.
toString
();
}
}
src/main/java/cn/qg/qaplatform/mock/encrypt/paycenter/Aes.java
0 → 100755
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
paycenter
;
import
javax.crypto.Cipher
;
import
javax.crypto.KeyGenerator
;
import
javax.crypto.spec.SecretKeySpec
;
import
java.io.UnsupportedEncodingException
;
import
java.security.Key
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.SecureRandom
;
public
class
Aes
{
private
static
final
int
KEY_LENGTH
=
16
;
/**
* 加密
*
* @param data 需要加密的内容
* @param key 加密密码
*/
public
static
byte
[]
encrypt
(
byte
[]
data
,
byte
[]
key
)
{
CheckUtils
.
notEmpty
(
data
,
"data"
);
CheckUtils
.
notEmpty
(
key
,
"key"
);
if
(
key
.
length
!=
KEY_LENGTH
)
{
throw
new
RuntimeException
(
"Invalid Aes key length (must be 16 bytes)"
);
}
try
{
SecretKeySpec
secretKey
=
new
SecretKeySpec
(
key
,
"Aes"
);
byte
[]
enCodeFormat
=
secretKey
.
getEncoded
();
SecretKeySpec
seckey
=
new
SecretKeySpec
(
enCodeFormat
,
"Aes"
);
Cipher
cipher
=
Cipher
.
getInstance
(
ConfigureEncryptAndDecrypt
.
AES_ALGORITHM
);
// 创建密码器
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
seckey
);
// 初始化
byte
[]
result
=
cipher
.
doFinal
(
data
);
return
result
;
// 加密
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"encrypt fail!"
,
e
);
}
}
/**
* 解密
*
* @param data 待解密内容
* @param key 解密密钥
*/
public
static
byte
[]
decrypt
(
byte
[]
data
,
byte
[]
key
)
{
CheckUtils
.
notEmpty
(
data
,
"data"
);
CheckUtils
.
notEmpty
(
key
,
"key"
);
if
(
key
.
length
!=
KEY_LENGTH
)
{
throw
new
RuntimeException
(
"Invalid Aes key length (must be 16 bytes)"
);
}
try
{
SecretKeySpec
secretKey
=
new
SecretKeySpec
(
key
,
"Aes"
);
byte
[]
enCodeFormat
=
secretKey
.
getEncoded
();
SecretKeySpec
seckey
=
new
SecretKeySpec
(
enCodeFormat
,
"Aes"
);
Cipher
cipher
=
Cipher
.
getInstance
(
ConfigureEncryptAndDecrypt
.
AES_ALGORITHM
);
// 创建密码器
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
seckey
);
// 初始化
byte
[]
result
=
cipher
.
doFinal
(
data
);
return
result
;
// 加密
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"decrypt fail!"
,
e
);
}
}
public
static
String
encryptToBase64
(
String
data
,
String
key
)
{
try
{
byte
[]
valueByte
=
encrypt
(
data
.
getBytes
(
ConfigureEncryptAndDecrypt
.
CHAR_ENCODING
),
key
.
getBytes
(
ConfigureEncryptAndDecrypt
.
CHAR_ENCODING
));
return
new
String
(
Base64
.
encode
(
valueByte
));
}
catch
(
UnsupportedEncodingException
e
)
{
throw
new
RuntimeException
(
"encrypt fail!"
,
e
);
}
}
public
static
String
decryptFromBase64
(
String
data
,
String
key
)
{
try
{
byte
[]
originalData
=
Base64
.
decode
(
data
.
getBytes
());
byte
[]
valueByte
=
decrypt
(
originalData
,
key
.
getBytes
(
ConfigureEncryptAndDecrypt
.
CHAR_ENCODING
));
return
new
String
(
valueByte
,
ConfigureEncryptAndDecrypt
.
CHAR_ENCODING
);
}
catch
(
UnsupportedEncodingException
e
)
{
throw
new
RuntimeException
(
"decrypt fail!"
,
e
);
}
}
public
static
String
encryptWithKeyBase64
(
String
data
,
String
key
)
{
try
{
byte
[]
valueByte
=
encrypt
(
data
.
getBytes
(
ConfigureEncryptAndDecrypt
.
CHAR_ENCODING
),
Base64
.
decode
(
key
.
getBytes
()));
return
new
String
(
Base64
.
encode
(
valueByte
));
}
catch
(
UnsupportedEncodingException
e
)
{
throw
new
RuntimeException
(
"encrypt fail!"
,
e
);
}
}
public
static
String
decryptWithKeyBase64
(
String
data
,
String
key
)
{
try
{
byte
[]
originalData
=
Base64
.
decode
(
data
.
getBytes
());
byte
[]
valueByte
=
decrypt
(
originalData
,
Base64
.
decode
(
key
.
getBytes
()));
return
new
String
(
valueByte
,
ConfigureEncryptAndDecrypt
.
CHAR_ENCODING
);
}
catch
(
UnsupportedEncodingException
e
)
{
throw
new
RuntimeException
(
"decrypt fail!"
,
e
);
}
}
public
static
byte
[]
genarateRandomKey
()
{
KeyGenerator
keygen
=
null
;
try
{
keygen
=
KeyGenerator
.
getInstance
(
ConfigureEncryptAndDecrypt
.
AES_ALGORITHM
);
}
catch
(
NoSuchAlgorithmException
e
)
{
throw
new
RuntimeException
(
" genarateRandomKey fail!"
,
e
);
}
SecureRandom
random
=
new
SecureRandom
();
keygen
.
init
(
random
);
Key
key
=
keygen
.
generateKey
();
return
key
.
getEncoded
();
}
public
static
String
genarateRandomKeyWithBase64
()
{
return
new
String
(
Base64
.
encode
(
genarateRandomKey
()));
}
}
src/main/java/cn/qg/qaplatform/mock/encrypt/paycenter/Base64.java
0 → 100755
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
paycenter
;
import
java.io.UnsupportedEncodingException
;
public
class
Base64
{
/**
* Chunk size per RFC 2045 section 6.8.
* <p/>
* <p>The {@value} character limit does not count the trailing CRLF, but counts
* all other characters, including any equal signs.</p>
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 6.8</a>
*/
static
final
int
CHUNK_SIZE
=
76
;
/**
* Chunk separator per RFC 2045 section 2.1.
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a>
*/
static
final
byte
[]
CHUNK_SEPARATOR
=
"\r\n"
.
getBytes
();
/**
* The basis length.
*/
static
final
int
BASELENGTH
=
255
;
/**
* Lookup length.
*/
static
final
int
LOOKUPLENGTH
=
64
;
/**
* Used to calculate the number of bits in a byte.
*/
static
final
int
EIGHTBIT
=
8
;
/**
* Used when encoding something which has fewer than 24 bits.
*/
static
final
int
SIXTEENBIT
=
16
;
/**
* Used to determine how many bits data contains.
*/
static
final
int
TWENTYFOURBITGROUP
=
24
;
/**
* Used to get the number of Quadruples.
*/
static
final
int
FOURBYTE
=
4
;
/**
* Used to test the sign of a byte.
*/
static
final
int
SIGN
=
-
128
;
/**
* Byte used to pad output.
*/
static
final
byte
PAD
=
(
byte
)
'='
;
// Create arrays to hold the base64 characters and a
// lookup for base64 chars
private
static
byte
[]
base64Alphabet
=
new
byte
[
BASELENGTH
];
private
static
byte
[]
lookUpBase64Alphabet
=
new
byte
[
LOOKUPLENGTH
];
// Populating the lookup and character arrays
static
{
for
(
int
i
=
0
;
i
<
BASELENGTH
;
i
++)
{
base64Alphabet
[
i
]
=
(
byte
)
-
1
;
}
for
(
int
i
=
'Z'
;
i
>=
'A'
;
i
--)
{
base64Alphabet
[
i
]
=
(
byte
)
(
i
-
'A'
);
}
for
(
int
i
=
'z'
;
i
>=
'a'
;
i
--)
{
base64Alphabet
[
i
]
=
(
byte
)
(
i
-
'a'
+
26
);
}
for
(
int
i
=
'9'
;
i
>=
'0'
;
i
--)
{
base64Alphabet
[
i
]
=
(
byte
)
(
i
-
'0'
+
52
);
}
base64Alphabet
[
'+'
]
=
62
;
base64Alphabet
[
'/'
]
=
63
;
for
(
int
i
=
0
;
i
<=
25
;
i
++)
{
lookUpBase64Alphabet
[
i
]
=
(
byte
)
(
'A'
+
i
);
}
for
(
int
i
=
26
,
j
=
0
;
i
<=
51
;
i
++,
j
++)
{
lookUpBase64Alphabet
[
i
]
=
(
byte
)
(
'a'
+
j
);
}
for
(
int
i
=
52
,
j
=
0
;
i
<=
61
;
i
++,
j
++)
{
lookUpBase64Alphabet
[
i
]
=
(
byte
)
(
'0'
+
j
);
}
lookUpBase64Alphabet
[
62
]
=
(
byte
)
'+'
;
lookUpBase64Alphabet
[
63
]
=
(
byte
)
'/'
;
}
private
static
boolean
isBase64
(
byte
octect
)
{
if
(
octect
==
PAD
)
{
return
true
;
}
else
{
return
base64Alphabet
[
octect
]
!=
-
1
;
}
}
/**
* Tests a given byte array to see if it contains
* only valid characters within the Base64 alphabet.
*
* @param arrayOctect byte array to test
* @return true if all bytes are valid characters in the Base64 alphabet or if the byte array is
* empty; false, otherwise
*/
public
static
boolean
isArrayByteBase64
(
byte
[]
arrayOctect
)
{
arrayOctect
=
discardWhitespace
(
arrayOctect
);
int
length
=
arrayOctect
.
length
;
if
(
length
==
0
)
{
// shouldn't a 0 length array be valid base64 data?
// return false;
return
true
;
}
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
if
(!
isBase64
(
arrayOctect
[
i
]))
{
return
false
;
}
}
return
true
;
}
/**
* Encodes binary data using the base64 algorithm but
* does not chunk the output.
*
* @param binaryData binary data to encode
* @return Base64 characters
*/
public
static
byte
[]
encodeBase64
(
byte
[]
binaryData
)
{
return
encodeBase64
(
binaryData
,
false
);
}
/**
* Encodes binary data using the base64 algorithm and chunks
* the encoded output into 76 character blocks
*
* @param binaryData binary data to encode
* @return Base64 characters chunked in 76 character blocks
*/
public
static
byte
[]
encodeBase64Chunked
(
byte
[]
binaryData
)
{
return
encodeBase64
(
binaryData
,
true
);
}
/**
* Decodes a byte[] containing containing
* characters in the Base64 alphabet.
*
* @param pArray A byte array containing Base64 character data
* @return a byte array containing binary data
*/
public
static
byte
[]
decode
(
byte
[]
pArray
)
{
return
decodeBase64
(
pArray
);
}
/**
* Encodes binary data using the base64 algorithm, optionally
* chunking the output into 76 character blocks.
*
* @param binaryData Array containing binary data to encode.
* @param isChunked if isChunked is true this encoder will chunk the base64 output into 76
* character blocks
* @return Base64-encoded data.
*/
public
static
byte
[]
encodeBase64
(
byte
[]
binaryData
,
boolean
isChunked
)
{
int
lengthDataBits
=
binaryData
.
length
*
EIGHTBIT
;
int
fewerThan24bits
=
lengthDataBits
%
TWENTYFOURBITGROUP
;
int
numberTriplets
=
lengthDataBits
/
TWENTYFOURBITGROUP
;
byte
encodedData
[]
=
null
;
int
encodedDataLength
=
0
;
int
nbrChunks
=
0
;
if
(
fewerThan24bits
!=
0
)
{
//data not divisible by 24 bit
encodedDataLength
=
(
numberTriplets
+
1
)
*
4
;
}
else
{
// 16 or 8 bit
encodedDataLength
=
numberTriplets
*
4
;
}
// If the output is to be "chunked" into 76 character sections,
// for compliance with RFC 2045 MIME, then it is important to
// allow for extra length to account for the separator(s)
if
(
isChunked
)
{
nbrChunks
=
(
CHUNK_SEPARATOR
.
length
==
0
?
0
:
(
int
)
Math
.
ceil
((
double
)
encodedDataLength
/
CHUNK_SIZE
));
encodedDataLength
+=
nbrChunks
*
CHUNK_SEPARATOR
.
length
;
}
encodedData
=
new
byte
[
encodedDataLength
];
byte
k
=
0
,
l
=
0
,
b1
=
0
,
b2
=
0
,
b3
=
0
;
int
encodedIndex
=
0
;
int
dataIndex
=
0
;
int
i
=
0
;
int
nextSeparatorIndex
=
CHUNK_SIZE
;
int
chunksSoFar
=
0
;
for
(
i
=
0
;
i
<
numberTriplets
;
i
++)
{
dataIndex
=
i
*
3
;
b1
=
binaryData
[
dataIndex
];
b2
=
binaryData
[
dataIndex
+
1
];
b3
=
binaryData
[
dataIndex
+
2
];
l
=
(
byte
)
(
b2
&
0x0f
);
k
=
(
byte
)
(
b1
&
0x03
);
byte
val1
=
((
b1
&
SIGN
)
==
0
)
?
(
byte
)
(
b1
>>
2
)
:
(
byte
)
((
b1
)
>>
2
^
0xc0
);
byte
val2
=
((
b2
&
SIGN
)
==
0
)
?
(
byte
)
(
b2
>>
4
)
:
(
byte
)
((
b2
)
>>
4
^
0xf0
);
byte
val3
=
((
b3
&
SIGN
)
==
0
)
?
(
byte
)
(
b3
>>
6
)
:
(
byte
)
((
b3
)
>>
6
^
0xfc
);
encodedData
[
encodedIndex
]
=
lookUpBase64Alphabet
[
val1
];
encodedData
[
encodedIndex
+
1
]
=
lookUpBase64Alphabet
[
val2
|
(
k
<<
4
)];
encodedData
[
encodedIndex
+
2
]
=
lookUpBase64Alphabet
[(
l
<<
2
)
|
val3
];
encodedData
[
encodedIndex
+
3
]
=
lookUpBase64Alphabet
[
b3
&
0x3f
];
encodedIndex
+=
4
;
// If we are chunking, let's put a chunk separator down.
if
(
isChunked
)
{
// this assumes that CHUNK_SIZE % 4 == 0
if
(
encodedIndex
==
nextSeparatorIndex
)
{
System
.
arraycopy
(
CHUNK_SEPARATOR
,
0
,
encodedData
,
encodedIndex
,
CHUNK_SEPARATOR
.
length
);
chunksSoFar
++;
nextSeparatorIndex
=
(
CHUNK_SIZE
*
(
chunksSoFar
+
1
))
+
(
chunksSoFar
*
CHUNK_SEPARATOR
.
length
);
encodedIndex
+=
CHUNK_SEPARATOR
.
length
;
}
}
}
// form integral number of 6-bit groups
dataIndex
=
i
*
3
;
if
(
fewerThan24bits
==
EIGHTBIT
)
{
b1
=
binaryData
[
dataIndex
];
k
=
(
byte
)
(
b1
&
0x03
);
byte
val1
=
((
b1
&
SIGN
)
==
0
)
?
(
byte
)
(
b1
>>
2
)
:
(
byte
)
((
b1
)
>>
2
^
0xc0
);
encodedData
[
encodedIndex
]
=
lookUpBase64Alphabet
[
val1
];
encodedData
[
encodedIndex
+
1
]
=
lookUpBase64Alphabet
[
k
<<
4
];
encodedData
[
encodedIndex
+
2
]
=
PAD
;
encodedData
[
encodedIndex
+
3
]
=
PAD
;
}
else
if
(
fewerThan24bits
==
SIXTEENBIT
)
{
b1
=
binaryData
[
dataIndex
];
b2
=
binaryData
[
dataIndex
+
1
];
l
=
(
byte
)
(
b2
&
0x0f
);
k
=
(
byte
)
(
b1
&
0x03
);
byte
val1
=
((
b1
&
SIGN
)
==
0
)
?
(
byte
)
(
b1
>>
2
)
:
(
byte
)
((
b1
)
>>
2
^
0xc0
);
byte
val2
=
((
b2
&
SIGN
)
==
0
)
?
(
byte
)
(
b2
>>
4
)
:
(
byte
)
((
b2
)
>>
4
^
0xf0
);
encodedData
[
encodedIndex
]
=
lookUpBase64Alphabet
[
val1
];
encodedData
[
encodedIndex
+
1
]
=
lookUpBase64Alphabet
[
val2
|
(
k
<<
4
)];
encodedData
[
encodedIndex
+
2
]
=
lookUpBase64Alphabet
[
l
<<
2
];
encodedData
[
encodedIndex
+
3
]
=
PAD
;
}
if
(
isChunked
)
{
// we also add a separator to the end of the final chunk.
if
(
chunksSoFar
<
nbrChunks
)
{
System
.
arraycopy
(
CHUNK_SEPARATOR
,
0
,
encodedData
,
encodedDataLength
-
CHUNK_SEPARATOR
.
length
,
CHUNK_SEPARATOR
.
length
);
}
}
return
encodedData
;
}
/**
* Decodes Base64 data into octects
*
* @param base64Data Byte array containing Base64 data
* @return Array containing decoded data.
*/
public
static
byte
[]
decodeBase64
(
byte
[]
base64Data
)
{
// RFC 2045 requires that we discard ALL non-Base64 characters
base64Data
=
discardNonBase64
(
base64Data
);
// handle the edge case, so we don't have to worry about it later
if
(
base64Data
.
length
==
0
)
{
return
new
byte
[
0
];
}
int
numberQuadruple
=
base64Data
.
length
/
FOURBYTE
;
byte
decodedData
[]
=
null
;
byte
b1
=
0
,
b2
=
0
,
b3
=
0
,
b4
=
0
,
marker0
=
0
,
marker1
=
0
;
// Throw away anything not in base64Data
int
encodedIndex
=
0
;
int
dataIndex
=
0
;
{
// this sizes the output array properly - rlw
int
lastData
=
base64Data
.
length
;
// ignore the '=' padding
while
(
base64Data
[
lastData
-
1
]
==
PAD
)
{
if
(--
lastData
==
0
)
{
return
new
byte
[
0
];
}
}
decodedData
=
new
byte
[
lastData
-
numberQuadruple
];
}
for
(
int
i
=
0
;
i
<
numberQuadruple
;
i
++)
{
dataIndex
=
i
*
4
;
marker0
=
base64Data
[
dataIndex
+
2
];
marker1
=
base64Data
[
dataIndex
+
3
];
b1
=
base64Alphabet
[
base64Data
[
dataIndex
]];
b2
=
base64Alphabet
[
base64Data
[
dataIndex
+
1
]];
if
(
marker0
!=
PAD
&&
marker1
!=
PAD
)
{
//No PAD e.g 3cQl
b3
=
base64Alphabet
[
marker0
];
b4
=
base64Alphabet
[
marker1
];
decodedData
[
encodedIndex
]
=
(
byte
)
(
b1
<<
2
|
b2
>>
4
);
decodedData
[
encodedIndex
+
1
]
=
(
byte
)
(((
b2
&
0xf
)
<<
4
)
|
((
b3
>>
2
)
&
0xf
));
decodedData
[
encodedIndex
+
2
]
=
(
byte
)
(
b3
<<
6
|
b4
);
}
else
if
(
marker0
==
PAD
)
{
//Two PAD e.g. 3c[Pad][Pad]
decodedData
[
encodedIndex
]
=
(
byte
)
(
b1
<<
2
|
b2
>>
4
);
}
else
if
(
marker1
==
PAD
)
{
//One PAD e.g. 3cQ[Pad]
b3
=
base64Alphabet
[
marker0
];
decodedData
[
encodedIndex
]
=
(
byte
)
(
b1
<<
2
|
b2
>>
4
);
decodedData
[
encodedIndex
+
1
]
=
(
byte
)
(((
b2
&
0xf
)
<<
4
)
|
((
b3
>>
2
)
&
0xf
));
}
encodedIndex
+=
3
;
}
return
decodedData
;
}
/**
* Discards any whitespace from a basis-64 encoded block.
*
* @param data The basis-64 encoded data to discard the whitespace from.
* @return The data, less whitespace (see RFC 2045).
*/
static
byte
[]
discardWhitespace
(
byte
[]
data
)
{
byte
groomedData
[]
=
new
byte
[
data
.
length
];
int
bytesCopied
=
0
;
for
(
int
i
=
0
;
i
<
data
.
length
;
i
++)
{
switch
(
data
[
i
])
{
case
(
byte
)
' '
:
case
(
byte
)
'\n'
:
case
(
byte
)
'\r'
:
case
(
byte
)
'\t'
:
break
;
default
:
groomedData
[
bytesCopied
++]
=
data
[
i
];
}
}
byte
packedData
[]
=
new
byte
[
bytesCopied
];
System
.
arraycopy
(
groomedData
,
0
,
packedData
,
0
,
bytesCopied
);
return
packedData
;
}
/**
* Discards any characters outside of the base64 alphabet, per
* the requirements on page 25 of RFC 2045 - "Any characters
* outside of the base64 alphabet are to be ignored in base64
* encoded data."
*
* @param data The basis-64 encoded data to groom
* @return The data, less non-base64 characters (see RFC 2045).
*/
static
byte
[]
discardNonBase64
(
byte
[]
data
)
{
byte
groomedData
[]
=
new
byte
[
data
.
length
];
int
bytesCopied
=
0
;
for
(
int
i
=
0
;
i
<
data
.
length
;
i
++)
{
if
(
isBase64
(
data
[
i
]))
{
groomedData
[
bytesCopied
++]
=
data
[
i
];
}
}
byte
packedData
[]
=
new
byte
[
bytesCopied
];
System
.
arraycopy
(
groomedData
,
0
,
packedData
,
0
,
bytesCopied
);
return
packedData
;
}
/**
* Encodes a byte[] containing binary data, into a byte[] containing
* characters in the Base64 alphabet.
*
* @param pArray a byte array containing binary data
* @return A byte array containing only Base64 character data
*/
public
static
byte
[]
encode
(
byte
[]
pArray
)
{
return
encodeBase64
(
pArray
,
false
);
}
public
static
String
encode
(
String
str
)
throws
UnsupportedEncodingException
{
String
baseStr
=
new
String
(
encode
(
str
.
getBytes
(
"UTF-8"
)));
String
tempStr
=
Digest
.
digest
(
str
).
toUpperCase
();
String
result
=
tempStr
+
baseStr
;
return
new
String
(
encode
(
result
.
getBytes
(
"UTF-8"
)));
}
public
static
String
decode
(
String
cryptoStr
)
throws
UnsupportedEncodingException
{
if
(
cryptoStr
.
length
()
<
40
)
{
return
""
;
}
try
{
String
tempStr
=
new
String
(
decode
(
cryptoStr
.
getBytes
(
"UTF-8"
)));
String
result
=
tempStr
.
substring
(
40
,
tempStr
.
length
());
return
new
String
(
decode
(
result
.
getBytes
(
"UTF-8"
)));
}
catch
(
ArrayIndexOutOfBoundsException
ex
)
{
return
""
;
}
}
/**
* Decodes Base64 data into octects
*
* @param encoded string containing Base64 data
* @return Array containind decoded data.
*/
public
static
byte
[]
decode2
(
String
encoded
)
{
if
(
encoded
==
null
)
{
return
null
;
}
char
[]
base64Data
=
encoded
.
toCharArray
();
// remove white spaces
int
len
=
removeWhiteSpace
(
base64Data
);
if
(
len
%
FOURBYTE
!=
0
)
{
return
null
;
//should be divisible by four
}
int
numberQuadruple
=
(
len
/
FOURBYTE
);
if
(
numberQuadruple
==
0
)
{
return
new
byte
[
0
];
}
byte
decodedData
[]
=
null
;
byte
b1
=
0
,
b2
=
0
,
b3
=
0
,
b4
=
0
;
char
d1
=
0
,
d2
=
0
,
d3
=
0
,
d4
=
0
;
int
i
=
0
;
int
encodedIndex
=
0
;
int
dataIndex
=
0
;
decodedData
=
new
byte
[(
numberQuadruple
)
*
3
];
for
(;
i
<
numberQuadruple
-
1
;
i
++)
{
if
(!
isData
((
d1
=
base64Data
[
dataIndex
++]))
||
!
isData
((
d2
=
base64Data
[
dataIndex
++]))
||
!
isData
((
d3
=
base64Data
[
dataIndex
++]))
||
!
isData
((
d4
=
base64Data
[
dataIndex
++])))
{
return
null
;
}
//if found "no data" just return null
b1
=
base64Alphabet
[
d1
];
b2
=
base64Alphabet
[
d2
];
b3
=
base64Alphabet
[
d3
];
b4
=
base64Alphabet
[
d4
];
decodedData
[
encodedIndex
++]
=
(
byte
)
(
b1
<<
2
|
b2
>>
4
);
decodedData
[
encodedIndex
++]
=
(
byte
)
(((
b2
&
0xf
)
<<
4
)
|
((
b3
>>
2
)
&
0xf
));
decodedData
[
encodedIndex
++]
=
(
byte
)
(
b3
<<
6
|
b4
);
}
if
(!
isData
((
d1
=
base64Data
[
dataIndex
++]))
||
!
isData
((
d2
=
base64Data
[
dataIndex
++])))
{
return
null
;
//if found "no data" just return null
}
b1
=
base64Alphabet
[
d1
];
b2
=
base64Alphabet
[
d2
];
d3
=
base64Data
[
dataIndex
++];
d4
=
base64Data
[
dataIndex
++];
if
(!
isData
((
d3
))
||
!
isData
((
d4
)))
{
//Check if they are PAD characters
if
(
isPad
(
d3
)
&&
isPad
(
d4
))
{
if
((
b2
&
0xf
)
!=
0
)
//last 4 bits should be zero
{
return
null
;
}
byte
[]
tmp
=
new
byte
[
i
*
3
+
1
];
System
.
arraycopy
(
decodedData
,
0
,
tmp
,
0
,
i
*
3
);
tmp
[
encodedIndex
]
=
(
byte
)
(
b1
<<
2
|
b2
>>
4
);
return
tmp
;
}
else
if
(!
isPad
(
d3
)
&&
isPad
(
d4
))
{
b3
=
base64Alphabet
[
d3
];
if
((
b3
&
0x3
)
!=
0
)
//last 2 bits should be zero
{
return
null
;
}
byte
[]
tmp
=
new
byte
[
i
*
3
+
2
];
System
.
arraycopy
(
decodedData
,
0
,
tmp
,
0
,
i
*
3
);
tmp
[
encodedIndex
++]
=
(
byte
)
(
b1
<<
2
|
b2
>>
4
);
tmp
[
encodedIndex
]
=
(
byte
)
(((
b2
&
0xf
)
<<
4
)
|
((
b3
>>
2
)
&
0xf
));
return
tmp
;
}
else
{
return
null
;
}
}
else
{
//No PAD e.g 3cQl
b3
=
base64Alphabet
[
d3
];
b4
=
base64Alphabet
[
d4
];
decodedData
[
encodedIndex
++]
=
(
byte
)
(
b1
<<
2
|
b2
>>
4
);
decodedData
[
encodedIndex
++]
=
(
byte
)
(((
b2
&
0xf
)
<<
4
)
|
((
b3
>>
2
)
&
0xf
));
decodedData
[
encodedIndex
++]
=
(
byte
)
(
b3
<<
6
|
b4
);
}
return
decodedData
;
}
private
static
boolean
isWhiteSpace
(
char
octect
)
{
return
(
octect
==
0x20
||
octect
==
0xd
||
octect
==
0xa
||
octect
==
0x9
);
}
private
static
boolean
isData
(
char
octect
)
{
return
(
octect
<
BASELENGTH
&&
base64Alphabet
[
octect
]
!=
-
1
);
}
private
static
boolean
isPad
(
char
octect
)
{
return
(
octect
==
PAD
);
}
/**
* remove WhiteSpace from MIME containing encoded Base64 data.
*
* @param data the byte array of base64 data (with WS)
* @return the new length
*/
private
static
int
removeWhiteSpace
(
char
[]
data
)
{
if
(
data
==
null
)
{
return
0
;
}
// count characters that's not whitespace
int
newSize
=
0
;
int
len
=
data
.
length
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
if
(!
isWhiteSpace
(
data
[
i
]))
{
data
[
newSize
++]
=
data
[
i
];
}
}
return
newSize
;
}
}
src/main/java/cn/qg/qaplatform/mock/encrypt/paycenter/CheckUtils.java
0 → 100755
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
paycenter
;
import
java.lang.reflect.Array
;
import
java.util.Collection
;
import
java.util.Map
;
public
class
CheckUtils
{
/**
* 验证对象是否为NULL,空字符串,空数组,空的Collection或Map(只有空格的字符串也认为是空串)
*
* @param obj 被验证的对象
* @param message 异常信息
*/
@SuppressWarnings
(
"rawtypes"
)
public
static
void
notEmpty
(
Object
obj
,
String
message
)
{
if
(
obj
==
null
)
{
throw
new
IllegalArgumentException
(
message
+
" must be specified"
);
}
if
(
obj
instanceof
String
&&
obj
.
toString
().
trim
().
length
()
==
0
)
{
throw
new
IllegalArgumentException
(
message
+
" must be specified"
);
}
if
(
obj
.
getClass
().
isArray
()
&&
Array
.
getLength
(
obj
)
==
0
)
{
throw
new
IllegalArgumentException
(
message
+
" must be specified"
);
}
if
(
obj
instanceof
Collection
&&
((
Collection
)
obj
).
isEmpty
())
{
throw
new
IllegalArgumentException
(
message
+
" must be specified"
);
}
if
(
obj
instanceof
Map
&&
((
Map
)
obj
).
isEmpty
())
{
throw
new
IllegalArgumentException
(
message
+
" must be specified"
);
}
}
}
src/main/java/cn/qg/qaplatform/mock/encrypt/paycenter/ConfigureEncryptAndDecrypt.java
0 → 100755
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
paycenter
;
public
class
ConfigureEncryptAndDecrypt
{
public
static
final
String
CHAR_ENCODING
=
"UTF-8"
;
public
static
final
String
AES_ALGORITHM
=
"Aes/ECB/PKCS5Padding"
;
public
static
final
String
RSA_ALGORITHM
=
"Rsa/ECB/PKCS1Padding"
;
}
src/main/java/cn/qg/qaplatform/mock/encrypt/paycenter/Digest.java
0 → 100755
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
paycenter
;
import
lombok.extern.slf4j.Slf4j
;
import
java.io.UnsupportedEncodingException
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
import
java.util.Arrays
;
@Slf4j
public
class
Digest
{
public
static
final
String
ENCODE
=
"UTF-8"
;
public
static
String
signMD5
(
String
aValue
,
String
encoding
)
{
try
{
byte
[]
input
=
aValue
.
getBytes
(
encoding
);
MessageDigest
md
=
MessageDigest
.
getInstance
(
"MD5"
);
return
AbstractConvertUtils
.
toHex
(
md
.
digest
(
input
));
}
catch
(
NoSuchAlgorithmException
e
)
{
log
.
error
(
"{}"
,
e
);
return
null
;
}
catch
(
UnsupportedEncodingException
e
)
{
log
.
error
(
"{}"
,
e
);
return
null
;
}
}
public
static
String
hmacSign
(
String
aValue
)
{
try
{
byte
[]
input
=
aValue
.
getBytes
();
MessageDigest
md
=
MessageDigest
.
getInstance
(
"MD5"
);
return
AbstractConvertUtils
.
toHex
(
md
.
digest
(
input
));
}
catch
(
NoSuchAlgorithmException
e
)
{
log
.
error
(
"{}"
,
e
);
return
null
;
}
}
public
static
String
hmacSign
(
String
aValue
,
String
aKey
)
{
return
hmacSign
(
aValue
,
aKey
,
ENCODE
);
}
public
static
String
hmacSign
(
String
aValue
,
String
aKey
,
String
encoding
)
{
byte
k_ipad
[]
=
new
byte
[
64
];
byte
k_opad
[]
=
new
byte
[
64
];
byte
keyb
[];
byte
value
[];
try
{
keyb
=
aKey
.
getBytes
(
encoding
);
value
=
aValue
.
getBytes
(
encoding
);
}
catch
(
UnsupportedEncodingException
e
)
{
keyb
=
aKey
.
getBytes
();
value
=
aValue
.
getBytes
();
}
Arrays
.
fill
(
k_ipad
,
keyb
.
length
,
64
,
(
byte
)
54
);
Arrays
.
fill
(
k_opad
,
keyb
.
length
,
64
,
(
byte
)
92
);
for
(
int
i
=
0
;
i
<
keyb
.
length
;
i
++)
{
k_ipad
[
i
]
=
(
byte
)
(
keyb
[
i
]
^
0x36
);
k_opad
[
i
]
=
(
byte
)
(
keyb
[
i
]
^
0x5c
);
}
MessageDigest
md
=
null
;
try
{
md
=
MessageDigest
.
getInstance
(
"MD5"
);
}
catch
(
NoSuchAlgorithmException
e
)
{
log
.
error
(
"{}"
,
e
);
return
null
;
}
md
.
update
(
k_ipad
);
md
.
update
(
value
);
byte
dg
[]
=
md
.
digest
();
md
.
reset
();
md
.
update
(
k_opad
);
md
.
update
(
dg
,
0
,
16
);
dg
=
md
.
digest
();
return
AbstractConvertUtils
.
toHex
(
dg
);
}
public
static
String
hmacSHASign
(
String
aValue
,
String
aKey
,
String
encoding
)
{
byte
k_ipad
[]
=
new
byte
[
64
];
byte
k_opad
[]
=
new
byte
[
64
];
byte
keyb
[];
byte
value
[];
try
{
keyb
=
aKey
.
getBytes
(
encoding
);
value
=
aValue
.
getBytes
(
encoding
);
}
catch
(
UnsupportedEncodingException
e
)
{
keyb
=
aKey
.
getBytes
();
value
=
aValue
.
getBytes
();
}
Arrays
.
fill
(
k_ipad
,
keyb
.
length
,
64
,
(
byte
)
54
);
Arrays
.
fill
(
k_opad
,
keyb
.
length
,
64
,
(
byte
)
92
);
for
(
int
i
=
0
;
i
<
keyb
.
length
;
i
++)
{
k_ipad
[
i
]
=
(
byte
)
(
keyb
[
i
]
^
0x36
);
k_opad
[
i
]
=
(
byte
)
(
keyb
[
i
]
^
0x5c
);
}
MessageDigest
md
=
null
;
try
{
md
=
MessageDigest
.
getInstance
(
"SHA"
);
}
catch
(
NoSuchAlgorithmException
e
)
{
log
.
error
(
"{}"
,
e
);
return
null
;
}
md
.
update
(
k_ipad
);
md
.
update
(
value
);
byte
dg
[]
=
md
.
digest
();
md
.
reset
();
md
.
update
(
k_opad
);
md
.
update
(
dg
,
0
,
20
);
dg
=
md
.
digest
();
return
AbstractConvertUtils
.
toHex
(
dg
);
}
public
static
String
digest
(
String
aValue
)
{
return
digest
(
aValue
,
ENCODE
);
}
public
static
String
digest
(
String
aValue
,
String
encoding
)
{
aValue
=
aValue
.
trim
();
byte
value
[];
try
{
value
=
aValue
.
getBytes
(
encoding
);
}
catch
(
UnsupportedEncodingException
e
)
{
value
=
aValue
.
getBytes
();
}
MessageDigest
md
=
null
;
try
{
md
=
MessageDigest
.
getInstance
(
"SHA"
);
}
catch
(
NoSuchAlgorithmException
e
)
{
log
.
error
(
"{}"
,
e
);
return
null
;
}
return
AbstractConvertUtils
.
toHex
(
md
.
digest
(
value
));
}
public
static
String
digest
(
String
aValue
,
String
alg
,
String
encoding
)
{
aValue
=
aValue
.
trim
();
byte
value
[];
try
{
value
=
aValue
.
getBytes
(
encoding
);
}
catch
(
UnsupportedEncodingException
e
)
{
value
=
aValue
.
getBytes
();
}
MessageDigest
md
=
null
;
try
{
md
=
MessageDigest
.
getInstance
(
alg
);
}
catch
(
NoSuchAlgorithmException
e
)
{
log
.
error
(
"{}"
,
e
);
return
null
;
}
return
AbstractConvertUtils
.
toHex
(
md
.
digest
(
value
));
}
public
static
String
udpSign
(
String
aValue
)
{
try
{
byte
[]
input
=
aValue
.
getBytes
(
"UTF-8"
);
MessageDigest
md
=
MessageDigest
.
getInstance
(
"SHA1"
);
return
new
String
(
Base64
.
encode
(
md
.
digest
(
input
)),
ENCODE
);
}
catch
(
Exception
e
)
{
return
null
;
}
}
}
src/main/java/cn/qg/qaplatform/mock/encrypt/paycenter/EncryUtil.java
0 → 100755
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
paycenter
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.TypeReference
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
java.util.Map.Entry
;
import
java.util.TreeMap
;
@Slf4j
public
class
EncryUtil
{
/**
* 生成RSA签名
*/
public
static
String
handleRSA
(
TreeMap
<
String
,
Object
>
map
,
String
privateKey
)
{
StringBuffer
sbuffer
=
new
StringBuffer
();
for
(
Entry
<
String
,
Object
>
entry
:
map
.
entrySet
())
{
sbuffer
.
append
(
entry
.
getValue
());
}
String
signTemp
=
sbuffer
.
toString
();
String
sign
=
""
;
if
(
StringUtils
.
isNotEmpty
(
privateKey
))
{
sign
=
Rsa
.
sign
(
signTemp
,
privateKey
);
}
return
sign
;
}
/**
* 对易宝支付返回的结果进行验签
*
* @param data 易宝支付返回的业务数据密文
* @param encrypt_key 易宝支付返回的对ybAesKey加密后的密文
* @param yibaoPublickKey 易宝支付提供的公钥
* @param merchantPrivateKey 商户自己的私钥
* @return 验签是否通过
* @throws Exception
*/
public
static
boolean
checkDecryptAndSign
(
String
data
,
String
encrypt_key
,
String
yibaoPublickKey
,
String
merchantPrivateKey
)
{
/** 1.使用YBprivatekey解开aesEncrypt。 */
String
AESKey
;
try
{
AESKey
=
Rsa
.
decrypt
(
encrypt_key
,
merchantPrivateKey
);
}
catch
(
Exception
e
)
{
/** AES密钥解密失败 */
log
.
error
(
"{}"
,
e
);
return
false
;
}
/** 2.用aeskey解开data。取得data明文 */
String
realData
=
Aes
.
decryptFromBase64
(
data
,
AESKey
);
TreeMap
<
String
,
String
>
map
=
JSON
.
parseObject
(
realData
,
new
TypeReference
<
TreeMap
<
String
,
String
>>()
{
});
/** 3.取得data明文sign。 */
String
sign
=
StringUtils
.
trimToEmpty
(
map
.
get
(
"sign"
));
StringBuilder
signData
=
new
StringBuilder
();
for
(
Entry
<
String
,
String
>
entry
:
map
.
entrySet
())
{
if
(
StringUtils
.
equals
(
entry
.
getKey
(),
"sign"
))
{
continue
;
}
signData
.
append
(
entry
.
getValue
()
==
null
?
""
:
entry
.
getValue
());
}
/** 5. result为true时表明验签通过 */
String
str
=
signData
.
toString
();
return
Rsa
.
checkSign
(
str
,
sign
,
yibaoPublickKey
);
}
}
src/main/java/cn/qg/qaplatform/mock/encrypt/paycenter/RandomUtil.java
0 → 100755
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
paycenter
;
import
java.security.SecureRandom
;
public
class
RandomUtil
{
public
static
final
SecureRandom
random
=
new
SecureRandom
();
public
static
String
getRandom
(
int
length
)
{
StringBuilder
ret
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
boolean
isChar
=
(
random
.
nextInt
(
2
)
%
2
==
0
);
// 输出字母还是数字
if
(
isChar
)
{
// 字符串
int
choice
=
random
.
nextInt
(
2
)
%
2
==
0
?
65
:
97
;
// 取得大写字母还是小写字母
ret
.
append
((
char
)
(
choice
+
random
.
nextInt
(
26
)));
}
else
{
// 数字
ret
.
append
(
Integer
.
toString
(
random
.
nextInt
(
10
)));
}
}
return
ret
.
toString
();
}
}
src/main/java/cn/qg/qaplatform/mock/encrypt/paycenter/Rsa.java
0 → 100644
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
encrypt
.
paycenter
;
import
java.math.BigInteger
;
import
java.security.Key
;
import
java.security.KeyFactory
;
import
java.security.KeyPair
;
import
java.security.KeyPairGenerator
;
import
java.security.PrivateKey
;
import
java.security.PublicKey
;
import
java.security.SecureRandom
;
import
java.security.Signature
;
import
java.security.interfaces.RSAPublicKey
;
import
java.security.spec.PKCS8EncodedKeySpec
;
import
java.security.spec.X509EncodedKeySpec
;
import
java.util.HashMap
;
import
java.util.Map
;
import
javax.crypto.Cipher
;
import
lombok.extern.slf4j.Slf4j
;
@Slf4j
public
class
Rsa
{
/**
* 指定key的大小
*/
private
static
int
KEYSIZE
=
1024
;
/**
* 生成密钥对
*/
public
static
Map
<
String
,
String
>
generateKeyPair
()
throws
Exception
{
/** RSA算法要求有一个可信任的随机数源 */
SecureRandom
sr
=
new
SecureRandom
();
/** 为RSA算法创建一个KeyPairGenerator对象 */
KeyPairGenerator
kpg
=
KeyPairGenerator
.
getInstance
(
"Rsa"
);
/** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
kpg
.
initialize
(
KEYSIZE
,
sr
);
/** 生成密匙对 */
KeyPair
kp
=
kpg
.
generateKeyPair
();
/** 得到公钥 */
Key
publicKey
=
kp
.
getPublic
();
byte
[]
publicKeyBytes
=
publicKey
.
getEncoded
();
String
pub
=
new
String
(
Base64
.
encodeBase64
(
publicKeyBytes
),
ConfigureEncryptAndDecrypt
.
CHAR_ENCODING
);
/** 得到私钥 */
Key
privateKey
=
kp
.
getPrivate
();
byte
[]
privateKeyBytes
=
privateKey
.
getEncoded
();
String
pri
=
new
String
(
Base64
.
encodeBase64
(
privateKeyBytes
),
ConfigureEncryptAndDecrypt
.
CHAR_ENCODING
);
Map
<
String
,
String
>
map
=
new
HashMap
<
String
,
String
>();
map
.
put
(
"publicKey"
,
pub
);
map
.
put
(
"privateKey"
,
pri
);
RSAPublicKey
rsp
=
(
RSAPublicKey
)
kp
.
getPublic
();
BigInteger
bint
=
rsp
.
getModulus
();
byte
[]
b
=
bint
.
toByteArray
();
byte
[]
deBase64Value
=
Base64
.
encodeBase64
(
b
);
String
retValue
=
new
String
(
deBase64Value
);
map
.
put
(
"modulus"
,
retValue
);
return
map
;
}
/**
* 加密方法 source: 源数据
*/
public
static
String
encrypt
(
String
source
,
String
publicKey
)
throws
Exception
{
Key
key
=
getPublicKey
(
publicKey
);
/** 得到Cipher对象来实现对源数据的RSA加密 */
Cipher
cipher
=
Cipher
.
getInstance
(
ConfigureEncryptAndDecrypt
.
RSA_ALGORITHM
);
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
);
byte
[]
b
=
source
.
getBytes
();
/** 执行加密操作 */
byte
[]
b1
=
cipher
.
doFinal
(
b
);
return
new
String
(
Base64
.
encodeBase64
(
b1
),
ConfigureEncryptAndDecrypt
.
CHAR_ENCODING
);
}
/**
* 解密算法 cryptograph:密文
*/
public
static
String
decrypt
(
String
cryptograph
,
String
privateKey
)
throws
Exception
{
Key
key
=
getPrivateKey
(
privateKey
);
/** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
Cipher
cipher
=
Cipher
.
getInstance
(
ConfigureEncryptAndDecrypt
.
RSA_ALGORITHM
);
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
key
);
byte
[]
b1
=
Base64
.
decodeBase64
(
cryptograph
.
getBytes
());
/** 执行解密操作 */
byte
[]
b
=
cipher
.
doFinal
(
b1
);
return
new
String
(
b
);
}
/**
* 得到公钥
*
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
public
static
PublicKey
getPublicKey
(
String
key
)
throws
Exception
{
X509EncodedKeySpec
keySpec
=
new
X509EncodedKeySpec
(
Base64
.
decodeBase64
(
key
.
getBytes
()));
KeyFactory
keyFactory
=
KeyFactory
.
getInstance
(
"Rsa"
);
PublicKey
publicKey
=
keyFactory
.
generatePublic
(
keySpec
);
return
publicKey
;
}
/**
* 得到私钥
*
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
public
static
PrivateKey
getPrivateKey
(
String
key
)
throws
Exception
{
PKCS8EncodedKeySpec
keySpec
=
new
PKCS8EncodedKeySpec
(
Base64
.
decodeBase64
(
key
.
getBytes
()));
KeyFactory
keyFactory
=
KeyFactory
.
getInstance
(
"Rsa"
);
PrivateKey
privateKey
=
keyFactory
.
generatePrivate
(
keySpec
);
return
privateKey
;
}
public
static
String
sign
(
String
content
,
String
privateKey
)
{
String
charset
=
ConfigureEncryptAndDecrypt
.
CHAR_ENCODING
;
try
{
PKCS8EncodedKeySpec
priPKCS8
=
new
PKCS8EncodedKeySpec
(
Base64
.
decodeBase64
(
privateKey
.
getBytes
()));
KeyFactory
keyf
=
KeyFactory
.
getInstance
(
"Rsa"
);
PrivateKey
priKey
=
keyf
.
generatePrivate
(
priPKCS8
);
Signature
signature
=
Signature
.
getInstance
(
"SHA1WithRSA"
);
signature
.
initSign
(
priKey
);
signature
.
update
(
content
.
getBytes
(
charset
));
byte
[]
signed
=
signature
.
sign
();
return
new
String
(
Base64
.
encodeBase64
(
signed
));
}
catch
(
Exception
e
)
{
}
return
null
;
}
public
static
boolean
checkSign
(
String
content
,
String
sign
,
String
publicKey
)
{
try
{
KeyFactory
keyFactory
=
KeyFactory
.
getInstance
(
"Rsa"
);
byte
[]
encodedKey
=
Base64
.
decode2
(
publicKey
);
PublicKey
pubKey
=
keyFactory
.
generatePublic
(
new
X509EncodedKeySpec
(
encodedKey
));
Signature
signature
=
Signature
.
getInstance
(
"SHA1WithRSA"
);
signature
.
initVerify
(
pubKey
);
signature
.
update
(
content
.
getBytes
(
"utf-8"
));
boolean
bverify
=
signature
.
verify
(
Base64
.
decode2
(
sign
));
return
bverify
;
}
catch
(
Exception
e
)
{
log
.
error
(
"{}"
,
e
);
}
return
false
;
}
}
src/main/java/cn/qg/qaplatform/mock/interceptor/PayInterceptor.java
View file @
296382a3
package
cn
.
qg
.
qaplatform
.
mock
.
interceptor
;
package
cn
.
qg
.
qaplatform
.
mock
.
interceptor
;
import
cn.qg.qaplatform.config.SwitchDataSource
;
import
cn.qg.qaplatform.config.SwitchDataSource
;
import
cn.qg.qaplatform.mock.encrypt.factory.EncryptConvertor
;
import
cn.qg.qaplatform.mock.encrypt.factory.EncryptFactory
;
import
cn.qg.qaplatform.mock.encrypt.paycenter.Aes
;
import
cn.qg.qaplatform.mock.encrypt.paycenter.Rsa
;
import
cn.qg.qaplatform.mock.entity.Mock
;
import
cn.qg.qaplatform.mock.entity.Mock
;
import
cn.qg.qaplatform.mock.mapper.MockMapper
;
import
cn.qg.qaplatform.mock.mapper.MockMapper
;
import
cn.qg.qaplatform.utils.JsonTransUtils
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.lang.Nullable
;
import
org.springframework.lang.Nullable
;
import
org.springframework.web.servlet.HandlerInterceptor
;
import
org.springframework.web.servlet.HandlerInterceptor
;
import
org.springframework.web.servlet.ModelAndView
;
import
org.springframework.web.servlet.ModelAndView
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.PrintWriter
;
import
java.io.PrintWriter
;
import
java.util.HashMap
;
import
java.util.Map
;
@Slf4j
@Slf4j
public
class
PayInterceptor
implements
HandlerInterceptor
{
public
class
PayInterceptor
implements
HandlerInterceptor
{
...
@@ -20,10 +30,29 @@ public class PayInterceptor implements HandlerInterceptor {
...
@@ -20,10 +30,29 @@ public class PayInterceptor implements HandlerInterceptor {
@Autowired
@Autowired
MockMapper
mockMapper
;
MockMapper
mockMapper
;
@Value
(
"${namespace}"
)
private
String
namespace
;
/**
* 获取HttpServletRequest的body
* @param request HttpServletRequest
* @return
* @throws IOException
*/
private
String
getRequestBody
(
HttpServletRequest
request
)
throws
IOException
{
BufferedReader
br
=
request
.
getReader
();
String
str
;
StringBuilder
wholeStr
=
new
StringBuilder
();
while
((
str
=
br
.
readLine
())
!=
null
){
wholeStr
.
append
(
str
);
}
return
wholeStr
.
toString
();
}
@Override
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
throws
Exception
{
throws
Exception
{
SwitchDataSource
.
dataSourceSwitch
(
"pre"
,
"qa"
);
SwitchDataSource
.
dataSourceSwitch
(
namespace
,
"qa"
);
String
uri
=
request
.
getRequestURI
().
substring
(
5
);
String
uri
=
request
.
getRequestURI
().
substring
(
5
);
QueryWrapper
<
Mock
>
queryWrapper
=
new
QueryWrapper
<>();
QueryWrapper
<
Mock
>
queryWrapper
=
new
QueryWrapper
<>();
queryWrapper
.
eq
(
"url"
,
uri
);
queryWrapper
.
eq
(
"url"
,
uri
);
...
@@ -31,12 +60,24 @@ public class PayInterceptor implements HandlerInterceptor {
...
@@ -31,12 +60,24 @@ public class PayInterceptor implements HandlerInterceptor {
response
.
setHeader
(
"Content-type"
,
"application/json;charset=UTF-8"
);
response
.
setHeader
(
"Content-type"
,
"application/json;charset=UTF-8"
);
response
.
setCharacterEncoding
(
"UTF-8"
);
response
.
setCharacterEncoding
(
"UTF-8"
);
PrintWriter
printWriter
=
response
.
getWriter
();
PrintWriter
printWriter
=
response
.
getWriter
();
// 对request进行解密
EncryptConvertor
encryptConvertor
=
EncryptFactory
.
produce
(
"yeebao"
);
Map
<
String
,
Object
>
requestMap
=
JsonTransUtils
.
strToMap
(
encryptConvertor
.
decrypt
(
getRequestBody
(
request
)));
Map
<
String
,
Object
>
responseMap
=
new
HashMap
<>();
if
(
mock
.
getFlag
().
equals
(
1
))
{
if
(
mock
.
getFlag
().
equals
(
1
))
{
printWriter
.
write
(
mock
.
getSuccess
());
responseMap
=
JsonTransUtils
.
strToMap
(
mock
.
getSuccess
());
}
else
if
(
mock
.
getFlag
().
equals
(
0
))
{
}
else
if
(
mock
.
getFlag
().
equals
(
0
))
{
printWriter
.
write
(
mock
.
getFail
());
responseMap
=
JsonTransUtils
.
strToMap
(
mock
.
getFail
());
}
}
// 对请求进行解密TF
// 如果response中存在变量,则使用requestMap中对应变量进行替换
for
(
Map
.
Entry
<
String
,
Object
>
entry:
responseMap
.
entrySet
())
{
String
value
=
(
String
)
entry
.
getValue
();
if
(
value
.
startsWith
(
"$request"
))
{
entry
.
setValue
(
requestMap
.
get
(
value
.
split
(
"\\."
)[
1
]));
}
}
// 对response加密
printWriter
.
write
(
encryptConvertor
.
encrypt
(
JsonTransUtils
.
mapToJson
(
responseMap
)));
return
true
;
return
true
;
}
}
...
@@ -52,4 +93,7 @@ public class PayInterceptor implements HandlerInterceptor {
...
@@ -52,4 +93,7 @@ public class PayInterceptor implements HandlerInterceptor {
log
.
info
(
"calling afterCompletion"
);
log
.
info
(
"calling afterCompletion"
);
}
}
public
static
void
main
(
String
[]
args
)
{
}
}
}
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