Skip to content

Instantly share code, notes, and snippets.

@fieldju
Created January 14, 2016 03:49
Show Gist options
  • Save fieldju/6c51e966388136df0bd4 to your computer and use it in GitHub Desktop.
Save fieldju/6c51e966388136df0bd4 to your computer and use it in GitHub Desktop.
POC for public private service to service auth mechinism
import groovy.json.JsonBuilder
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import org.joda.time.format.DateTimeFormatter
import org.joda.time.format.ISODateTimeFormat
import java.security.KeyPair
import java.security.KeyPairGenerator
import java.security.PrivateKey
import java.security.PublicKey
import java.security.Signature
@GrabResolver(name="jcenter", root="http://jcenter.bintray.com/", m2Compatible=true)
@GrabResolver(name="codehaus", root="http://repository.codehaus.org/", m2Compatible=true)
/**
* The dependencies
*/
@Grapes([
@Grab(group='joda-time', module='joda-time', version='2.9.1')
])
class Token {
DateTime notBefore
DateTime notAfter
Token() {
DateTime now = DateTime.now().withZone(DateTimeZone.UTC)
notBefore = now.minusMinutes(5)
notAfter = now.plusMinutes(5)
}
@Override
String toString() {
DateTimeFormatter formatter = ISODateTimeFormat.dateTime()
new JsonBuilder([
notBefore: formatter.print(notBefore),
notAfter: formatter.print(notAfter)
]).toString()
}
}
class Service {
private final MockDynamoDB mockDynamoDB
Service() {
mockDynamoDB = new MockDynamoDB()
}
Token generateToken() {
return new Token()
}
String generateSignatureForToken(Token token, String keyId) {
PrivateKey privateKey = mockDynamoDB.getPrivateKey(keyId)
Signature rsa = Signature.getInstance("SHA1withRSA")
rsa.initSign(privateKey)
rsa.update(token.toString().bytes)
String sig = rsa.sign().encodeBase64().toString()
println "Generated sig: ${sig}"
return sig
}
boolean verifySignatureForToken(Token token, String signature, String keyId) {
try {
PublicKey publicKey = mockDynamoDB.getPublicKey(keyId)
Signature rsa = Signature.getInstance("SHA1withRSA")
rsa.initVerify(publicKey)
rsa.update(token.toString().bytes)
boolean verified = rsa.verify(signature.decodeBase64())
assert verified, "Failed to verify token and signature"
println "SUCCESS | token: $token was signed with keyid: ${keyId}"
} catch (Exception e) {
println "failed to verify token signature: ${e.getMessage()}"
assert false
}
}
}
class MockDynamoDB {
static final Map<String, KeyPair> data = [:]
PrivateKey getPrivateKey(String keyId) {
return getKeyPair(keyId).private
}
PublicKey getPublicKey(String keyId) {
return getKeyPair(keyId).public
}
private KeyPair getKeyPair(String keyId) {
KeyPair keyPair = data.get(keyId)
if (keyPair == null) {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA")
kpg.initialize(2058)
keyPair = kpg.genKeyPair()
data.put(keyId, keyPair)
}
return keyPair
}
}
def main() {
Service a = new Service()
Service b = new Service()
String keyId = "ServiceAKey"
Token serviceAToken = a.generateToken()
String serviceASignature = a.generateSignatureForToken(serviceAToken, keyId)
boolean verified = b.verifySignatureForToken(serviceAToken, serviceASignature, keyId)
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment