Use grok to break it into three parts. You could use GREEDYDATA to capture middleBit, but I have an aversion for using GREEDYDATA anywhere except in last place. Then you can use dissect or csv for the middle bit, and kv for the end.
grok { match => { "message" => '^(?<ts>[^;]+);(?<middleBit>[^"]+);"%{DATA:restOfLine}"' } }
dissect { mapping => { "middleBit" => "%{[middle][a]};%{[middle][b]};%{[middle][c]};%{[middle][d]};%{[middle][e]}" } }
kv { source => "restOfLine" target => "keys" field_split => "," }